見出し画像

【アルゴリズム】株取引で利益を最大にするには?Javascriptでチャレンジしてみよう。


自動取引プログラムじゃないので、悪しからず。

株取引で利益を得る方法は、安く買って、高く売るですね。これは配列の要素を、株価の値動きに見立てた問題です。

言い換えると、

連続した数字の配列があるとすると、差分の最大値はいくつか?

例えば、配列 [32,46,26,38,40,48,42,1]があったとすると、最大の利得は「22」になります。つまり、「26」の時に買って、「48」で売るわけです。

注意点は、配列内の差分の最大値だけ見ると「47」です。ただ、数字は時系列に並んでいるもとしますので、これは最大の利得にはなりません。時間軸に沿って取引します。「1」が来るのは、株価が「48」になったあと。(ショート取引は無いもとします。)

実装例 O(n)

function maxStockProfit(priceArr) {
 var maxProfit = -1;
 var buyPrice = 0;
 var sellPrice = 0;
 var chageBuyPrice = true;

 for (let i = 0; i < priceArr.length; i++) {
   if (chageBuyPrice) buyPrice = priceArr[i];
   sellPrice = priceArr[i + 1];

   if (sellPrice < buyPrice) {
     chageBuyPrice = true;
   } else {
     var tempProfit = sellPrice - buyPrice;
     if (tempProfit > maxProfit) maxProfit = tempProfit;
     chageBuyPrice = false;
   }
 }

 return maxProfit;
}

//console.log(maxStockProfit([10, 18, 4, 5, 9, 16, 12]));

ポイントになるのは、chageBuyPriceというフラグを用意することです。買値(buyPrice)売値(sellPrice)を、上回っている時だけchageBuyPriceをtrueにして、評価する要素を前に動かしていきます。

売値(sellPrice)が、買値(buyPrice)を上回った時のみ、差分を出すようにします。

順に追っていきましょう。

10, 18, 4, 5, 9, 16, 12  //利得 8
↑    ↑
10, 18, 4, 5, 9, 16, 12 
↑       ↑
10, 18, 4, 5, 9, 16, 12   //利得 1
        ↑  ↑
10, 18, 4, 5, 9, 16, 12   //利得 5
        ↑      ↑
10, 18, 4, 5, 9, 16, 12  //利得 12 
        ↑         ↑
10, 18, 4, 5, 9, 16, 12  //利得 8
        ↑            ↑

「4」以降、sellPriceの方が高いので、buyPriceは動いていません。

アルゴリズムで分からなくなったら、要素数を減らして、出力してみましょう。アルゴリズムは、一気に実装できなくても問題無いです。

ちなみに、フラグを取っ払った、ナイーブな解法は以下になります。計算量は膨大になりますね。。

一工夫するだけ、ずいぶんと高速になりますね。

ナイーブな解法 O(n^2)

function maxStockProfit(priceArr) {
 var tempProfit = 0;
 var maxProfit = -1;

 for (let i = 0; i < priceArr.length; i++) {
   for (let j = i + 1; j < priceArr.length - 1; j++) {
     if (priceArr[i] < priceArr[j]) tempProfit = priceArr[j] - priceArr[i];
     if (tempProfit > maxProfit) maxProfit = tempProfit;
   }
 }
 return maxProfit;
}


日常に潜む問題をアルゴリズムで効率的にする。読んでいてワクワクします。


この記事が気に入ったらサポートをしてみませんか?