Beispiel #1
0
 def trend_least_square(self, prices, diff_vals, cutoff, mult):
     diff = self.find_matches(diff_vals, cutoff, mult)
     temp_prices = self.match_indexes(diff, prices)
     inter, slope = Helper.least_square(temp_prices)
     return Straight(inter, slope, 0, self.sim_vars.analysisRange), diff
    def run_algo(self, stock):
        try:
            print "Running Stochastic: %s" % (stock,)

            # Parameters
            long_mov_avg_range = 50
            short_mov_avg_range = 20
            k_size = 5
            d_size = 3
            atr_size = 14

            # State vars
            day_close = False
            in_trade = ""
            atr = None

            # Plotting vars
            plot_data = []
            trade_data = []
            sma_short_data = [0] * long_mov_avg_range
            sma_long_data = [0] * long_mov_avg_range
            atr_data = [0] * long_mov_avg_range
            enter_index = 0
            bought_time = 0
            bought_price = 0

            trades = []

            # Read data in
            data = Helper.read_data_file(self.data_file_loc + stock + self.data_file_ext)

            for i in range(0, len(data) - long_mov_avg_range, 1):
                prices = data[i: i+long_mov_avg_range+1]
                closes = []
                for j in range(0, len(prices)):
                    prices[j].index = j
                    closes.append(prices[j].close)

                close = closes[-2]

                # Check for day changes
                day_close = Helper.check_day_change(prices[-2].timestamp, prices[-1].timestamp, self.sim_vars.samplePeriod)

                # Perform sma checks
                sma_long = self.ind.simple_moving_average(closes[0:long_mov_avg_range])
                sma_short = self.ind.simple_moving_average(closes[-short_mov_avg_range-1:-1])

                stochastics = []
                # We need to populate this first using stochastic(5,3)
                # In cases where high=low this value doesnt make sense
                try:
                    for j in range(d_size, 0, -1):
                        per_k = self.ind.stochastic(prices[-k_size-j-1:-j-1])
                        stochastics.append(per_k)
                except:
                    continue
                per_d = self.ind.simple_moving_average(stochastics)

                # Need to subtract 1 extra to get prev close
                atr = self.ind.average_true_range(prices[-1-atr_size-1:-1], atr)

                long_in_range = prices[-2].close < prices[-3].high
                short_in_range = prices[-2].close > prices[-3].high

                # So far we only look at 2 most recent data for candle type
                candle_type = self.ind.candle_type(prices[-3:-1])

                if sma_short > sma_long and \
                   per_k < 25 and per_d < 25 and \
                   "bullish" in candle_type and \
                   long_in_range:
                        in_trade = "long"
                        bought_price = close
                        bought_time = prices[-2].timestamp
                        trade_data = prices
                        enter_index = len(prices)-2
                elif sma_short < sma_long and \
                    per_k > 75 and per_d > 75 and \
                    "bearish" in candle_type and \
                    short_in_range:
                        in_trade = "short"
                        bought_price = close
                        bought_time = prices[-2].timestamp
                        trade_data = prices
                        enter_index = len(prices)-2

                exit_price = bought_price + 2*atr if in_trade == "long" else bought_price - 2*atr
                sl_price = bought_price - atr if in_trade == "long" else bought_price + atr

                # Check for trade exit point
                exit_trade = False
                stop = False
                if in_trade == "long":
                    exit_trade = True if prices[-2].close > exit_price else False
                    stop = True if prices[-2].close < sl_price else False
                elif in_trade == "short":
                    exit_trade = True if prices[-2].close < exit_price else False
                    stop = True if prices[-2].close > sl_price else False

                # Store extra data when in trade for plotting
                if in_trade:
                    trade_data.append(prices[-1])

                sma_short_data.append(sma_short)
                sma_long_data.append(sma_long)
                atr_data.append(atr)

                # Exit trade
                if (day_close or exit_trade or stop) and in_trade != "":
                    plot_url = ""
                    # Plot the data
                    if self.sim_vars.plotting:
                        line = Scatter(trade_data)
                        x_vals = [i for i in range(0, len(trade_data)-1)]
                        plot_data = []
                        plot_data.append(self.plot.gen_line(line.x, line.y, 'Stock Data'))
                        plot_data.append(self.plot.gen_line(x_vals, len(x_vals)*[exit_price], 'Exit Point', 1, 'dash'))
                        plot_data.append(self.plot.gen_line(x_vals, len(x_vals)*[sl_price], 'Stop Loss Point', 1, 'dash'))
                        plot_data.append(self.plot.gen_line(x_vals, sma_long_data[-len(trade_data):], 'Long Mov Avg'))
                        plot_data.append(self.plot.gen_line(x_vals, sma_short_data[-len(trade_data):], 'short Mov Avg'))
                        plot_data.append(self.plot.gen_point(enter_index, bought_price, 'Enter Price'))
                        plot_data.append(self.plot.gen_point(len(trade_data)-2, prices[-2].close, 'Exit Price'))

                        subplot_data = []
                        subplot_data.append(self.plot.gen_line(x_vals, atr_data[-len(trade_data):], 'ATR(14)'))
                        plot_url = self.plot.generate_subplots(str(self.run_id) + " " + in_trade + " " + stock + " " + str(prices[-2].timestamp), [plot_data, subplot_data])
                        #plot_url = self.plot.generate_a_graph(str(self.var_id) + " " + in_trade + " " + stock + " " + str(prices[-2].timestamp), plot_data)

                    if self.sim_vars.database:
                        # Store trade in DB
                        trade = PlotTrade(in_trade, bought_time, prices[-2].timestamp,
                                          bought_price, prices[-2].close,
                                          "", plot_url,
                                          exit_price, sl_price,
                                          None, None, None, stock)

                        db_trade = DBTrade(stock, self.run_id, trade)
                        trades.append(db_trade)
                        '''self.db.insert_item(db_trade)
                        print "inserted trade with id: " + str(db_trade.id)'''

                    in_trade = ""

            return trades
        except Exception, e:
            traceback.print_exc()
Beispiel #3
0
    def run_algo(self, stock):
        finished_trades = []
        print "Running SR: %s" % (stock,)
        splits = []

        data = Helper.read_data_file(self.data_file_loc + stock + self.data_file_ext)
        # Not all stocks have split data
        try:
            splits = Helper.read_split_file(self.split_file_loc + stock + self.split_file_ext)
        except:
            None

        trades = []
        short_buffer_zone = False
        long_buffer_zone = False

        for i in range(0, len(data) - self.sim_vars.analysisRange, self.sim_vars.stepSize):
            prices = data[i: i+self.sim_vars.analysisRange]
            for j in range(0, len(prices)):
                prices[j].index = j
            close = prices[-1].close

            cur_split = Split(1.0, 0)
            for split in splits:
                if split.timestamp < prices[-1].timestamp < (split.timestamp + 86400):
                    cur_split = split

            # Check if we can exit trade
            finished_trades.extend(self.check_exit(trades, prices[-1], cur_split))

            # Find least square line of all prices
            inter, slope = Helper.least_square(prices)
            mean_least_square = Straight(inter, slope, 0, self.sim_vars.analysisRange)
            y_vals = mean_least_square.y_vals
            diff_vals = [prices[z].close - y_vals[z] for z in range(0, len(prices))]

            # Generate least square trend lines
            (res_least_square, res_diff) = self.trend_least_square(prices, diff_vals, self.sim_vars.resCutoff, 1)
            (sup_least_square, sup_diff) = self.trend_least_square(prices, diff_vals, self.sim_vars.supCutoff, -1)

            res_val = res_least_square.y_vals[-1]
            sup_val = sup_least_square.y_vals[-1]

            # Generate range to enter trade
            max_long_buy_point = sup_val + (res_val-sup_val)*self.sim_vars.resMaxBuyPer/100
            min_long_buy_point = sup_val + (res_val-sup_val)*self.sim_vars.resMinBuyPer/100

            max_short_sell_point = res_val - (res_val-sup_val)*self.sim_vars.supMinBuyPer/100
            min_short_sell_point = res_val - (res_val-sup_val)*self.sim_vars.supMaxBuyPer/100

            if long_buffer_zone or short_buffer_zone:

                # Find sections of line that have matches
                pos_matches = [False, False, False]
                neg_matches = [False, False, False]
                for k in range(0, 3):
                    for diff in res_diff:
                        if (k+1)*(len(prices))//3 > diff.index > k*(len(prices))//3:
                            pos_matches[k] = True
                    for diff in sup_diff:
                        if (k+1)*(len(prices))//3 > diff.index > k*(len(prices))//3:
                            neg_matches[k] = True

                buy_point, sell_point, pot_buy, actual_type = Helper.trendType(res_least_square.slope,
                                                                  sup_least_square.slope, res_least_square.intercept,
                                                                  sup_least_square.intercept,
                                                                  self.sim_vars.analysisRange, self.sim_vars.supMinBuyPer/100.0,
                                                                  self.sim_vars.resMinBuyPer/100.0, close,
                                                                  self.sim_vars.analysisRange-1, self.sim_vars.analysisRange-1)

                #only consider buying when support matches in middle and at least one side
                long_pot_buy = pot_buy and (neg_matches[1] and (neg_matches[0] or neg_matches[2])) \
                    and (pos_matches[1] and (pos_matches[0] and pos_matches[2]))
                short_pot_buy = long_pot_buy

                if self.sim_vars.longStocks and long_buffer_zone and sell_point > close*(1.0 + self.sim_vars.minimumPercent/100.0) and long_pot_buy:
                    if min_long_buy_point <= close <= max_long_buy_point:

                        long_buffer_zone = False

                        t = PlotTrade("long", prices[-1].timestamp, None, close, None, None, None, sell_point,
                            close - close*self.sim_vars.stopLossPerc/100.0, prices, sup_least_square, res_least_square, stock)
                        t.mean_line = mean_least_square
                        trades.append(t)
                elif self.sim_vars.shortStocks and short_buffer_zone and buy_point < close/(1.0 + self.sim_vars.minimumPercent/100.0) and short_pot_buy:
                    if min_short_sell_point <= close <= max_short_sell_point:

                        short_buffer_zone = False

                        t = PlotTrade("short", prices[-1].timestamp, None, close, None, None, None, buy_point,
                            close + close*self.sim_vars.stopLossPerc/100, prices, sup_least_square, res_least_square, stock)
                        t.mean_line = mean_least_square
                        trades.append(t)

            # We only want to allow trades if we go below a buffer zone
            # Check if within buffer zone
            if sup_val + (res_val-sup_val)*(self.sim_vars.bufferPercent/100.0) >= close:
                long_buffer_zone = True
            elif close < min_long_buy_point and long_buffer_zone:
                long_buffer_zone = True
            else:
                long_buffer_zone = False

            if res_val - (res_val-sup_val)*(self.sim_vars.bufferPercent/100.0) <= close:
                short_buffer_zone = True
            elif close > max_short_sell_point and short_buffer_zone:
                short_buffer_zone = True
            else:
                short_buffer_zone = False

        return finished_trades