Find buy/sell prices in array of stock values to maximize positive difference Find buy/sell prices in array of stock values to maximize positive difference arrays arrays

Find buy/sell prices in array of stock values to maximize positive difference


In C#:

static void Main(string[] args){    double[] values = new double[7]{55.39, 109.23, 48.29, 81.59, 105.53, 94.45, 12.24};    double max = double.MinValue, maxDiff = double.MinValue, diff = 0;    for (int i = 1; i < values.Length; i++)    {        if (values[i] > values[i - 1])        {            //trending upward, append to existing differential            diff += values[i] - values[i - 1];        }        else        {            //trending downward, reset the diff            diff = 0;        }        if (diff > maxDiff)        {            maxDiff = diff;            max = values[i];        }    }    Console.WriteLine("Buy at {0}; Sell at {1}", max - maxDiff, max);}

EDIT: New algo based on @Joe's failing test case -- Nice Catch BTW! It's also the same answer as @Doug T's now...

static void Main(string[] args){    double[] values = new double[8] { 55.39, 109.23, 48.29, 81.59, 81.58, 105.53, 94.45, 12.24 };    double max = double.MinValue, maxDiff = double.MinValue, diff = 0;    double bottom = values[0];    for (int i = 1; i < values.Length; i++)    {        diff += values[i] - values[i - 1];        if (diff > maxDiff)        {            maxDiff = diff;            max = values[i];        }        if (values[i] < bottom)        {            bottom = values[i];            diff = 0;        }    }    Console.WriteLine("Buy at {0}; Sell at {1}", max - maxDiff, max);}


Here's an attempt (C++). Basically everytime I track a new top, I try to see if thats the best profit thusfar. I know that the "bottom" must have been discovered earlier. At that point I remember the top, bottom, and the current max profit. If a new bottom is discovered later, its AFTER the current top, so we must reset top and see if a slightly lower "top" can yield better profit.

#include <iostream>int main(){    double REALLY_BIG_NO = 1e99;    double bottom = REALLY_BIG_NO; // arbirtrary large number    double currBestBuy = 0.0;    double top = 0.0;    double currBestSell = 0.0;    double profit = 0.0;    // array of prices    double prices[] = {10.50, 55.39, 109.23, 48.29, 81.59, 105.53, 94.45, 12.24, 152.0, 2, 170.0};    int numPrices = 10;// number of prices    for (int i = 0; i < numPrices; ++i)    {         if (prices[i] < bottom)         {            bottom = prices[i];            // reset the search on a new bottom            top = 0.0;         }         else if (prices[i] > top)         {            top = prices[i];           // calculate profit            double potentialProfit = (top - bottom);            if (potentialProfit > profit &&                bottom != REALLY_BIG_NO)            {                profit = potentialProfit;                currBestSell = top;                currBestBuy = bottom;            }         }    }    std::cout << "Best Buy: " << currBestBuy << "Best Sell: " << currBestSell << std::endl;}

So far I've played around with a bunch of different input sets, and so far I haven't had any problems... (let me know if you test this and see anything wrong)

I highly recommend using Austin Salonen's updated answer to this question and adapting it to your language.


The idea is simple. Keep two pointers, lo and hi.
Do a Foor loop

  1. if price is higher than hi, update hi = price, continue
  2. if the price is lower than hi. Then lo and hi is one of possible candidates. Calculate the profit, store it if it's bigger than previous profits and reset lo, hi to price

def getBestProfit(prices):    lo = hi = profit = 0

for price in prices: if lo == 0 and hi == 0: lo = hi = price if price > hi: hi = price if price < low: tmpProfit = hi - lo if tmpProfit > profit: profit = tmpProfit lo = hi = price return profit

That's it