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()
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