我正在尝试在Ruby上执行股票选择器方法,但是我的代码中存在一些问题

时间:2019-03-24 04:37:52

标签: ruby

我正在尝试采用一种股票选择器方法,该方法采用一系列股票价格,每个假设天使用一个股票价格。它应返回代表最佳购买日和最佳出售日的两天。天数从0开始。

def stock_picker stocks
  pair = []

  if stocks.size < 2
    return "Please enter an array with a valid number of stocks"
  else
    buy_day = 0
    sell_day = 0
    profit = 0

    stocks.each_with_index do |buy, index|
      i = index
      while (i < stocks[index..-1].size)
        if ((buy - stocks[i]) > profit)
          profit = buy - stocks[i]
          buy_day = stocks.index(buy)
          sell_day = i
        end
        i+= 1
      end

    end
    pair = [buy_day,sell_day]
    return pair.inspect
  end
end

stock_picker([17,3,6,9,15,8,6,1,10])

它应该返回[1,4]而不是[0,7]

3 个答案:

答案 0 :(得分:1)

您可以遍历stock_prices数组,选择正差最大的日期。您的while条件需要更改。

#steps
#sets value of biggest_profit to 0(biggest_loss if looking for loss)
#sets most_profitable_days to [nil,nil]
#loops through array
#takes buy day
#loops through remainder of array
#if current day-first day>biggest_profit (first_day-current_day for loss)
#make >= for shortest holding period
#reassign biggest_profit
#most_profitable_days.first=buy_day, most_profitable_days.last=sell_day
#sell_day & buy_day are values of indices

#tests
#must accept only array
#must return array
#must return correct array

def stock_picker(arr)

    #checks to make sure array inputs only are given
    raise 'Only arrays allowed' unless arr.instance_of?(Array)

    #sets value of biggest_profit to 0(biggest_loss if looking for loss)
    biggest_profit=0

    #sets most_profitable_days to [nil,nil]
    most_profitable_days=[nil,nil]

    #loops through array
    arr.each_with_index do |starting_price, buy_day|

        #takes buy day
        arr.each_with_index do |final_price,sell_day|

            #loops through remainder of array
            next if sell_day<=buy_day

            #if current day-first day>biggest_profit (first_day-current_day for loss)
            #make '>=' for shortest holding period
            if final_price-starting_price>=biggest_profit

              #reassign biggest_profit
              biggest_profit=final_price-starting_price

              #most_profitable_days.first=buy_day, 
              most_profitable_days[0]=buy_day#+1 #to make it more user friendly

              #most_profitable_days.last=sell_day
              most_profitable_days[-1]=sell_day#+1 #to make it more user friendly
            end
        end
    end
    
  #return most_profitable_days
  most_profitable_days
end
p stock_picker([3,2,5,4,12,3]) #[1,4]

答案 1 :(得分:0)

使用Array#combination

stocks.
    each_with_index.
    to_a.
    combination(2).
    select { |(_, idx1), (_, idx2)| idx2 > idx1 }.
    reduce([-1, [-1, -1]]) do |(val, acc), ((v1, idx1), (v2, idx2))|
  val < v2 - v1 ? [v2 - v1, [idx1, idx2]] : [val, acc]
end
#⇒ [ 12, [1, 4] ]

答案 2 :(得分:0)

另一种选择是在对数组进行切片的同时对其进行迭代以获取最佳利润:

res = ary.each_with_index.with_object([]) do |(buy_val, i), res|
  highest_val = ary[i..].max
  highest_idx = ary[i..].each_with_index.max[1] + i
  res << [highest_val - buy_val, i, highest_idx]
end.max_by(&:first)

#=> [12, 1, 4]

其中12是利润,1是买入指数,4是卖出指数。


要了解其工作原理,请运行此扩展版本,它比任何书面解释都有价值:

res = []
ary.each_with_index do |buy_val, i|
  p buy_val
  p ary[i..]
  p highest_val = ary[i..].max
  p highest_idx = ary[i..].each_with_index.max[1] + i
  res << [highest_val - buy_val, i, highest_idx]
  p '----'
end

res #=> [[0, 0, 0], [12, 1, 4], [9, 2, 4], [6, 3, 4], [0, 4, 4], [2, 5, 8], [4, 6, 8], [9, 7, 8], [0, 8, 8]]

在Ruby标准库中,我使用了Enumerable#each_with_indexEnumerable#each_with_objectEnumerable#maxEnumerable#max_by


为了获得最大值的索引,我谨从Chuck(https://stackoverflow.com/a/2149874)那里窃取,谢谢和+1。我没有寻找更好的选择。

根据链接文章中Cary Swoveland的评论:

  

[..] a.index(a.max)将返回第一个索引和   a.each_with_index.max[1]将返回最后一个[..]

的索引

因此,也许您想使用第一个选项来缩短买卖之间的时间。