スタック取引所証券取引所-V3


42

注意:このチャレンジは終了しました:私はリーダーボードを更新しなくなり、受け入れられた回答を変更しません。ただし、必要に応じて、コントローラーを自由に実行し、リーダーボードを自分で更新できます。

チャットに参加してください!

前書き

こんばんは、トレーダー!あなたはすべてゴルフ会社PPCGのトレーダーです。あなたの仕事は、できるだけ多くのお金を稼ぐことです。

チャレンジ

できるだけ多くのお金を稼ぐことを目的として、Stack Exchange Stock Exchangeで株式を売買するプログラムを作成します。

ゲームプレイ

すべてのプレイヤーは、自分の銀行で5株と100ドルで始めます。ゲームは常に10ドルの株価で始まります。

各ゲームには1000ラウンドがあり、最初のラウンドはラウンド1です。各ラウンドでは、プログラムに入力として4つの引数が提供されます。現在の株価、所有する株式数、所有する金額、およびラウンド番号(1から始まる)。

たとえば、私のプログラムがtest1.py、株価が100、保有株式数が、保有3金額が1200、ラウンド数がの576場合、私のプログラムは次のように実行されます。

python test1.py 100 3 1200 576

ラウンドでは、各プレイヤーに与えられる株価は同じになります。これはラウンドの終わりまで変わりません。

応答として、プレーヤーはコマンドを印刷する必要があります。次の2つのオプションがあります。

  • 購入共有:このコマンドは次のように与えられているbn場所nあなたが購入したい株式数です。たとえば、100株を購入する場合、次のように出力します。
b100

株式を購入する場合、最大1000ドルの当座借越が許可されます。この当座借越を超える十分な株式を購入しようとすると(銀行の残高が$ -1000を下回ります)、破産と宣言されます。これは、すべての株式を失い、残高が50ドルに設定されることを意味します。

破産しても株価は指揮の影響を受けません。

(残高が$ -1000であれば、破産していません。ただし、残高が$ -1001であれば、破産しています)

  • 売る株式:このコマンドは次のように与えられているsn場所nあなたが販売することを希望する株式数です。たとえば、100株を販売する場合、次のように出力します。
s100

所有する株式よりも多くの株式を売却することはできません。これを行おうとすると、リクエストは拒否され、ラウンドはスキップされます。

ラウンドをスキップして何もしない場合は、b0またはのいずれかを出力しますs0

負の数の株式や整数以外の数の株式を売買しようとすると、リクエストは拒否されます。

5ラウンド後、各ラウンドの終わりに、すべてのプレーヤーに配当が支払われます。その価値は、最後の5ラウンドの平均株価の5%です。

どのように機能しますか?

当初の株価は10ドルです。各ラウンドの終わりに、式を使用して再計算されます:

New Share Price=Old Share Price+(Number of shares boughtNumber of shares sold)

株価は、1ドルを下回らないように制限されます。

急激な変化を防ぐため、株価の変更は最大制限されています。±$200

ルール

  • プログラムには名前が必要です


  • プログラムには、データストレージ用の単一のテキストファイルが許可されています。プログラムと同じフォルダーに保存する必要があります


  • プログラムの実行方法の詳細を回答に含めてください


  • このKotHは、無料で使用でき、Windows 10で実行できるすべてのプログラミング言語に対応しています。


  • スコアは、残高の内容のみに基づいています。株式に閉じ込められたお金はカウントされません


  • プログラムはいつでも編集できます。各ゲームの前に、最新のコードが保存され、コンパイルされます


  • 特に別のボットを標的とするコードを書くべきではありません。

コントローラ

コントローラーはPythonで書かれており、こちらにあります:https : //gist.github.com/beta-decay/a6abe40fc9f4ff6cac443395377ec31f

最後に、リーダーボードを印刷し、ゲーム全体で株価がどのように変化したかのグラフを表示します。

たとえば、2つのランダムボットが遊んでいたとき

勝ち

最後のゲームの終了時に残高が最も高いプレイヤーが勝ちます。

リーダーボード

ゲーム4:16:14 10/08/2018

Name                                Balance

Experienced Greedy Idiot            $14802860126910608746226775271608441476740220190868405578697473058787503167301288688412912141064764060957801420415934984247914753474481204843420999117641289792179203440895025689047561483400211597324662824868794009792985857917296068788434607950379253177065699908166901854516163240207641611196996217004494096517064741782361827125867827455285639964058498121173062045074772914323311612234964464095317202678432969866099864014974786854889944224928268964434751475446606732939913688961295787813863551384458839364617299883106342420461998689419913505735314365685264187374513996061826694192786379011458348988554845036604940421113739997490412464158065355335378462589602228039730
Equalizer                           $763185511031294813246284506179317396432985772155750823910419030867990447973211564091988995290789610193513321528772412563772470011147066425321453744308521967943712734185479563642323459564466177543928912648398244481744861744565800383179966018254551412512770699653538211331184147038781605464336206279313836606330
Percentage Trader                   $448397954167281544772103458977846133762031629256561243713673243996259286459758487106045850187688160858986472490834559645508673466589151486119551222357206708156491069820990603783876340193236064700332082781080188011584263709364962735827741094223755467455209136453381715027369221484319039100339776026752813930
OYAIB                               $8935960891618546760585096898089377896156886097652629690033599419878768424984255852521421137695754769495085398921618469764914237729576710889307470954692315601571866328742408488796145771039574397444873926883379666840494456194839899502761180282430561362538663182006432392949099112239702124912922930
Chimps on a Typewriter              $176504338999287847159247017725770908273849738720252130115528568718490320252556133502528055177870
Greedy B*****d                      $17689013777381240
Illiterate Dividend Investor        $2367418699671980
Lucky Number 6                      $4382725536910
Lone Accountant                     $90954970320
Buy/Reinvest                        $127330
Technical Analysis Robot            $126930
Dollar Cost Averager                $106130
Fibonacci                           $69930
Novice Broker                       $28130
Buy Low                             $6130
Naive Statistician                  $6130
Fallacious Gambler                  $6130
Passive Trader                      $4980
Half More or Nothing                $4920
Monkeys on a Typewriter             $66

各競技者のグラフを表示する


関連していますが、ゲームプレイと勝利基準はこの課題とは非常に異なります。


コメントは詳細なディスカッション用ではありません。この会話はチャットに移動さました
デニス

私にとっては、式は赤で[Math Processing Error]と表示されます。他の人も同じですか?もしそうなら、それは質問の問題かもしれません。
キャプテンマン

2
運の影響を減らすには、たとえば10〜100ゲームで結果を平均する価値があるかもしれません。または、それが挑戦を大きく変えすぎているのかもしれません。
mbrig

1
スコアをlog2 / log10にすることは可能でしょうか?スコアの比較がはるかに簡単になります。(私は自分の電話でブラウジングし、指数は画面から消えました)

1
私は10-100でも少なすぎると思いますが、私は多くのゲームを実行するの好きです。これを可能にするには、チャレンジの形式を変更する必要がありますが、現在は範囲外です。
ネイサンメリル

回答:


11

経験豊富な貪欲な白痴

PHP> = 7でテストされたPHPは、以前のものでも動作するはずです。

<?php

class StickExchange
{
    private $dbFile;
    private $sharePrice;
    private $shares;
    private $balance;
    private $overdraft;

    public function __construct($sharePrice, $shares, $balance, $round)
    {
        $this->dbFile = __FILE__ . '.txt';
        $this->sharePrice = gmp_init($sharePrice);
        $this->shares = gmp_init($shares);
        $this->balance = gmp_init($this->parseScientificNotationToInt($balance));
        $this->overdraft = gmp_init(1000);

        $action = 'b';

        if ($round == 1) {
            $this->buy();
        } elseif ($round == 1000) {
            $this->sell();
        } else {
            $content = $this->getDbContent();
            $lastPrice = gmp_init($content['price']);
            $secondLastPrice = gmp_init($content['last_price']);
            $lastAction = $content['action'];

            $shareAndLastCmp = gmp_cmp($this->sharePrice, $lastPrice);
            $lastAndSecondLastCmp = gmp_cmp($lastPrice, $secondLastPrice);

            if ($shareAndLastCmp > 0 && $lastAndSecondLastCmp > 0) {
                if ($lastAction == 'b') {
                    $this->sell();
                    $action = 's';
                } else {
                    $this->buy();
                }
            } elseif ($shareAndLastCmp < 0 && $lastAndSecondLastCmp < 0) {
                if ($lastAction == 'b') {
                    $this->sell();
                    $action = 's';
                } else {
                    $this->skip();
                }
            } elseif ($shareAndLastCmp > 0) {
                $this->sell();
                $action = 's';
            } elseif ($shareAndLastCmp < 0) {
                $this->buy();
            } else {
                $this->skip();
            }
        }

        $this->setDbContent([
            'action' => $action,
            'price' => gmp_strval($this->sharePrice),
            'last_price' => isset($lastPrice) ? gmp_strval($lastPrice) : '0',
        ]);
    }

    private function parseScientificNotationToInt($number)
    {
        if (strpos($number, 'e+') !== false) {
            $sParts = explode('e', $number);
            $parts = explode('.', $sParts[0]);
            $exp = (int)$sParts[1];

            if (count($parts) > 1) {
                $number = $parts[0] . $parts[1];
                $exp -= strlen($parts[1]);
            } else {
                $number = $parts[0];
            }

            $number = gmp_init($number);
            $pow = gmp_pow(gmp_init(10), $exp);
            return gmp_strval(gmp_mul($number, $pow));
        } elseif (strpos($number, 'e-') !== false) {
            return sprintf('%d', $number);
        } else {
            $parts = explode('.', $number);
            return $parts[0];
        }
    }

    private function getDbContent()
    {
        return unserialize(file_get_contents($this->dbFile));
    }

    private function setDbContent($content)
    {
        file_put_contents($this->dbFile, serialize($content));
    }

    private function buy()
    {
        $realBalance = gmp_add($this->balance, $this->overdraft);
        $sharesToBuy = gmp_div($realBalance, $this->sharePrice);
        $this->stdout('b' . gmp_strval($sharesToBuy));
    }

    private function sell()
    {
        $this->stdout('s' . gmp_strval($this->shares));
    }

    private function skip()
    {
        $this->stdout('b0');
    }

    private function stdout($string)
    {
        $stdout = fopen('php://stdout', 'w');
        fputs($stdout, $string);
        fclose($stdout);
    }
}

new StickExchange($argv[1], $argv[2], $argv[3], $argv[4]);

「The Greedy Idiot」の更新バージョン。再構築された動作と、膨大な数の処理に関連するバグ修正。

ノート:

  • ファイルに保存して、次のように実行します。 php C:\path\path\stack_exchange.php 10 5 100 1
  • このスクリプトは、スクリプトファイルと同じ名前で.txt末尾に追加されたテキストファイルを作成します。そのため、スクリプトパスに対する適切な書き込み権限を持つユーザーで実行してください。
  • WindowsにPHP 7.2をインストールする簡単な方法:http : //www.dorusomcutean.com/how-to-install-php-7-2-on-windows/
  • 超巨大な数値を扱うにはGMPを使用するphp.ini必要があったため、次の2行のコメントを外す必要があります(行の先頭のセミコロンがまだ削除されていない場合は削除する必要があります)。
    • ; extension_dir = "ext"
    • ;extension=gmp

1
うわー、そのリンクをありがとう!私が思っていた:D
ベータ崩壊

1
@BetaDecay:問題ありません。ステップ2(テストPHPがインストールされている)までインストールする必要があるだけですphp -v。これには残りは必要ありません。このチャレンジのために非常に多くの異なる言語を設定するのにあなたは多くの問題を抱えていると思います!私はこのようなことを敢えて決してしないだろう:D
Night2

@BetaDecayは、TryItOnlineをDockerコンテナとしてインストールする方が簡単ではないでしょうか?
-NieDzejkob

@NieDzejkobおそらくそれはおそらく、これらの言語がインストールされて便利になるだろう
ベータ崩壊

1
おめでとうございます、あなたは常に他のすべての競技者を打ち負かしました!
ベータ崩壊

19

タイプライターのチンパンジー

import random
from sys import argv

share_price = int(argv[1])
share_count = int(argv[2])
balance = float(argv[3])

x = random.random()
if x < 0.5:
    max_buy = balance / share_price
    buy_count = int(max_buy * random.random())
    print('b' + str(buy_count))
else:
    sell_count = int(share_count * random.random())
    print('s' + str(sell_count))

チンパンジーはサルよりも賢く、手に入らない株を購入したり、持っていない株を売ったりしません。

ただし、それ以外の場合はかなりランダムです。

python3で実行しますが、python2でも動作するはずです(?)


1
彼らは賢いかもしれませんが、彼らは幸運ですか?
ウーフージン

私のすべてのテストでこれがトップになったので、はい
Skidsdev

26
私はこれが最初のラウンドで20桁以上勝ったことに非常に興味があります
-mbrig

私は単純さの芸術にそれを置くのが好きです。他の誰もがボットを過剰に設計しています。
Skidsdev

1
これは非常に多くの愛を得ました、間違って:P
Night2

10

オヤイブ

from sys import argv

share_price = float(argv[1])
shares      = int(argv[2])
cash        = float(argv[3])
cur_round   = int(argv[4])
tot_rounds  = 1000.0

investments = shares * share_price
total_assets = investments + cash

target_cash = round(cur_round / tot_rounds * total_assets)

if target_cash > cash:
  shares_to_sell = min(shares, round((target_cash - cash) / share_price))
  print('s%d' % shares_to_sell)
else:
  shares_to_buy = round((cash - target_cash) / share_price)
  print('b%d' % shares_to_buy)

「あなたの年齢を債券で所有する」という古い言葉に続いて、このプログラムは同じことを試みます。このように、ゲーム終了時に市場の変動の影響を受けません。

編集:コントローラーを見ると、完全な株式のみを購入/販売できますが、端数口座残高があることを示しています。


PPCGへようこそ!
ベータ崩壊

ありがとうございました!初めて投稿するので、何か不適当な点があれば教えてください。
-just_browsing

最後のラウンドで、すべての株を売るという追加の条件を追加することもできます(investmentsスコアにはカウントされません)。
ライキング

2
それがOYAIBの美しさです。それは自動的に行われます。target_cashは、「ライフ」のどのポイントにあるかに応じて、total_assetsの割合です。終了時には、target_cashはtotal_assetsの100%であるため、保有している株式はすべて売却されます。
-just_browsing

9

孤独な会計士

buy-sell.py

from sys import argv

Price = int(argv[1])
Shares = int(argv[2])
Balance = float(argv[3])
Round = int(argv[4])

if Round % 2 == 0: print('s' + str(Shares))
if Round % 2 == 1: print('b' + str(int((Balance + 1000) / Price)))

には何も保存しませんbuy-sell.txt

奇数ラウンドでは、できるだけ多くの株式を購入します。偶数ラウンドでは、すべての株式を売却します。

その目的は、最初にできるだけ多くの株式を購入して株価を上げ、次にそれらの株式を売却してより多くのお金を稼ぐことです。最終ラウンドは偶数(ラウンド1000)であるため機能します。

5ラウンドの各ペアの後、株価は同じ()のままになりますが(ボットが単独であるため、ローン会計士であると仮定)、ボットの残高は増加します。より多くの株式を購入する能力。それは悪循環ですが、良い意味で(私にとって)。

主要な脆弱性は、悪意のあるボットが一緒に遊んで、株価を下げるために売ることにあります(どちらが良いかはわかりません)。この場合、邪悪なボットが十分にあれば、ボットの残高は$ -890のままになる可能性があります。この会計士は本当に彼らの心の平和を望んでいます。;-)


1対1これを破ることが可能かどうかわかりません。会計士LAを完全に理解し、それに対抗しようとしても簡単ではありません。あなたが数で勝っている大衆ゲームでは、あなたは打ち負かされる可能性があります。
ヤック

@Yakk他の人はすでに私のテストでこれを打ち負かしています。
エリックアウトゴルファー

1対1?私は困惑しています。相手がどのように価格変動を逆転させるほど金持ちになれるのか、あるいはリソースの山を燃やさずに時間の経過とともに規模が大きくなるのを防ぐこともできません(LAは犠牲を払わないので、やめる)。LAが1対1で負けたゲームプレイにリンクできますか?
-Yakk

@Yakkまだ1対1でテストしていません。また、必要に応じてチャットルームで議論することもできます。
エリックアウトゴルファー

株式があり、価格が前のラウンドよりも低い場合、またはお金があり、価格が高い場合、何もしない方が堅牢でしょうか?他の同様のボットと同期しないようにします。また、これがどのように1対1で打ち負かされるかわかりません。
JollyJoker

5

パッシブトレーダー

from sys import argv

share_price = int(argv[1])
balance = float(argv[3])
round_num = int(argv[4])

if round_num == 1:
    print('b%s' % str(int(balance / share_price)))
else:
    print('b0')

この男は、この「株式」のこと全体ではそれほど大きくはありませんが、彼が今少しお金を使うだけなら、彼は時間をかけて少しのお金を手に入れ、それは彼が使った金額以上になると聞きました。

彼は$ 0になるのに十分な株を買います(このファラの当座貸越はありません、彼は少しの利益のために借金をしませんでした)、そして配当を積み上げます

python3で実行しますが、python2でも同様に動作するはずです。


1
少なくとも最後のラウンドで15株を売るべきだと思います。
カルド

14
@Kaldo nah、彼はその時点までに株式を購入したことを長い間忘れていました
-Skidsdev

5

割合トレーダーPython3

(おそらくpython2で動作します)

import sys
args=sys.argv

price=int(args[1])
held=int(args[2])
money=int(args[3])
roundNum=int(args[4])
prevPrice=0

if roundNum==1:
    print("b"+str((money+1000)//price))
else:
    if roundNum==1000:
        print("s"+str(held))
    else:
        with open("percentageTrader.dat","r") as f:
            prevPrice=int(f.read())
        if(price>prevPrice):
            toSell=int(held*int(1000000*(price-prevPrice))/(price))//1000000
            print("s"+str(toSell))
        if(price<prevPrice):
            toBuy=int(((money+1000)//price)*int(1000000*(prevPrice-price))//(prevPrice))//1000000
            print("b"+str(toBuy))
        if(price==prevPrice):
            print("b0")

with open("percentageTrader.dat","w") as f:
    f.write(str(price))

実行手順

  • filename.pyとして保存
  • python filename.py price #shares balance round#で実行します

使い方

  • 最初のラウンドでは、ボットはできるだけ多くのシェアを購入します。
  • 価格が上昇した場合、ボットは価格の上昇率(新しい値から計算)に等しい割合の株式を販売します
  • 価格が低下した場合、ボットは価格の低下率に等しい購入可能最大株の割合を購入します(以前の値から計算)
  • ラウンド1000ですべてを売る

変更により、浮動小数点除算に起因する問題をうまく解決できるはずです。


4

ナイーブ統計学者

Python 3用に作成され、Python 2で動作する可能性があります

from sys import argv
from math import floor

# Save an entry to the stock history
def save_history(price):
    with open('stockhistory.txt', 'a') as f:
        f.write(str(price) + '\n')

# Load the stock history
def load_history():
    with open('stockhistory.txt', 'r') as f:
        return [float(line.strip()) for line in f]

# Calculate average price rise/fall streak length
def average_streak(history, condition):
    streaks = []
    current_streak = 0
    last_price = history[0]
    for price in history[1:]:
        if condition(last_price, price):
            current_streak += 1
        elif current_streak:
            streaks += [current_streak]
            current_streak = 0
        last_price = price
    if current_streak:
        streaks += [current_streak]
    return sum(streaks) / len(streaks) if streaks else None

# Calculate the current streak length
def current_streak(history, condition):
    streak = 0
    while streak < len(history) - 1 and condition(history[-streak - 2], history[-streak - 1]):
        streak += 1
    return streak

def run(share_price, share_count, balance, round_number):
    save_history(share_price)

    # Sell all shares if it is the last round
    if round_number == 1000:
        print('s' + str(int(share_count)))
        return

    # Buy as many shares as possible if the price is down to one, as there's
    # nothing to lose
    if share_price == 1:
        buy_count = int(balance + 1000)
        print('b' + str(buy_count))
        return

    history = load_history()

    # Calculate the average and current rise/fall streaks
    average_rise = average_streak(history, lambda a, b: a <= b)
    current_rise = current_streak(history, lambda a, b: a <= b)
    average_fall = average_streak(history, lambda a, b: a >= b)
    current_fall = current_streak(history, lambda a, b: a >= b)

    # Do nothing if there's no analyzed data
    if not average_fall or not average_rise:
        print('b0')
        return

    # Buy shares if the current rise streak is as long as or longer than average
    if current_rise > current_fall and current_rise >= average_rise:
        buy_count = (balance + 1000) / share_price
        print('b' + str(int(buy_count)))
        return

    # Sell shares if the current fall streak is as long as or longer than average
    if current_fall > current_rise and current_fall >= average_fall:
        print('s' + str(int(share_count)))
        return

    # Otherwise, do nothing    
    print('b0')

run(*map(float, argv[1:]))

これはナイーブな統計学者で、価格が通常より長く上昇/下落した場合にのみ買い/売り、株価が1つ下がった場合に株を買い、最後のラウンドですべての株を売ることによって株価を予測しようとします。


4

ドルコストアベレージャー

(Python 3.7でテスト済み)

codegolfの最初の投稿なので、何か間違ったことをしたかどうかを教えてください。

基本的な考え方は、可能であればラウンドごとに1株を購入し、最後にすべての株を売却することです。

from sys import argv
share_price = int(argv[1])
share_count = int(argv[2])
balance = float(argv[3])
round = int(argv[4])

if round < 1000:
    if balance > share_price-1000:
        print("b1")
    else:
        print("b0")
else:
    print("s" + str(share_count))

4

イコライザ

from sys import argv
p, n, b, r = map(int, argv[1:])
c = p*n
print "bs"[(c+b)/2>b] + str(int(abs(((c-b)/2)/p))) if r < 999.5 else "s" + str(int(n))

最後を除くすべてのラウンドで、現金と株式の間で均等に財源を分割します。私はこの戦略が少なくともいくらかのお金を稼ぐ数学的に健全な方法であると信じていますが、私は間違っていると証明されるかもしれません。

キャッチしていないバグがあるかもしれませんし、ないかもしれません。また、ややゴルフ。


私はラインを変更することをお勧めしたいので、あなたのプログラムは、ここに関与多数の困難を持っているp, n, b, r = map(float, argv[1:])p, n, b, r = map(int, argv[1:])
ベータ崩壊

@BetaDecay完了
エイダンF.ピアース

4

タイプライターの猿

import random

cmd = ['b', 's'][int(random.random() * 2)]
num = str(int(random.random() * 1000000))
print("%s%s" % (cmd, num))

それはタイプライターの猿の束です。X株をランダムに売買します。
0 <= X <= 1,000,000

python3で実行しますが、python2でも動作するはずです(?)


4
なぜcmd=random.choose(['b','s'])andを使用しないのnum = str(random.randint(0, 1000000))ですか?
ベータ崩壊

1
怠け者だから
Skidsdev

1
理由だけではありませんimport lazy
ウフジン

全体をfrom random import randint, choice;print("{}{}".format(choice(["b", "s"]), randint(0, 1e6)));-P
アーロンF

6
はい。ただし、これはゴルフのチャレンジではありません
Skidsdev

4

低購入

(Python 2または3)

import random

def run(price, shares, balance, round_):
    # We get no value from our leftover shares at the end, so sell them all.
    if round_ == 1000:
        print('s' + str(int(shares)))
        return

    # If the price is low enough, buy everything we can.
    if price <= 20 + round_ * 60:
        print('b' + str((balance + 1000) // price))
        return

    # If we have no shares, wait for the price to drop.
    if shares == 0:
        print('b0')
        return

    # Sometimes sell shares so we can buy if the price gets low again.
    if random.random() < 0.4:
        print('s1')
        return

    # Otherwise, just wait for a better price.
    print('b0')


if __name__ == '__main__':
    import sys
    run(*[float(x) for x in sys.argv[1:]])

3

ファラシャスギャンブラー

(Python 2または3)

import random

def run(price, shares, balance, round_):
    # We get no value from our leftover shares at the end, so sell them all.
    if round_ == 1000:
        print('s' + str(int(shares)))
        return

    # For the first round, just watch.
    if round_ == 1:
        with open('fg.txt', 'w') as f:
            f.write('1 0 10')
        print('b0')
        return

    # Get the state.
    with open('fg.txt') as f:
        direction, streak, previous = map(int, f.read().strip().split())
    change = price - previous

    # If the market isn't moving, wait for it to get hot again.
    if change == 0:
        print('b0')
        return

    # Keep track of the market direction.
    if (change > 0) == (direction > 0):
        streak += 1
    else:
        streak = 0
        direction *= -1

    # If the market's been going one way for too long, it has to switch, right?
    if streak > 5:
        if direction > 0:
            print('s' + str(shares // 2))
        else:
            print('b' + str((balance + 1000) // price // 2))
    # Otherwise, the market's too volatile.
    else:
        print('b0')

    # Save the state.
    with open('fg.txt', 'w') as f:
        f.write('%d %d %d' % (direction, streak, price))


if __name__ == '__main__':
    import sys
    run(*[float(x) for x in sys.argv[1:]])

3

(Dyalog)APL Farmer

r←apl_stock_farmer args
 round←¯1↑args
 :If 1=round
     (buyPrice sellPrice)←10 0
     bought←1
     (currPrice shares balance)←3↑args
     r←'b10'
 :ElseIf 1000=round
     r←'s',⍕shares
 :Else
     (currPrice shares balance)←3↑args
     :If (currPrice>buyPrice)∧bought
         bought←0
         sellPrice←currPrice
         r←'s',⍕shares
     :ElseIf (currPrice<sellPrice)∧~bought
         bought←1
         buyPrice←currPrice
         r←'b',⍕⌊(1000+balance)÷currPrice
     :Else
         r←'b0'
     :End
 :End

最初のラウンドですべての可能な株式を購入し、現在の価格が購入価格よりも高い場合にのみ販売するTradFn。ボットは、販売後、最後に販売した株式よりも安い株式のみを購入します。

農民の会計士が彼に、あなたが株取引をする方法だと言ったからです。「低価格で購入、高価格で販売」など。

免責事項

これはKotHチャレンジでの最初の試みであり、基本的にここでAPLのみを行うため、それを続けることにしました。

とは言っても、これはTradfnであり、CMD / Bashシェルに直接フィードできないため、他のボットと一緒に実行できるかどうかは完全にはわかりません。

したがって、これをBashで実行するには、次のコマンドが必要です。

$ echo apl_stock_farmer args | dyalog 'stock_exchange.dws' -script

どこ:

apl_stock_farmer は、コードの最初の行にある関数の名前です。

argsスペースで区切られた引数のベクトルです(最初のラウンドでは、になります10 5 100 1)。

dyalog Dyalog実行可能ファイルへのパスです

'stock_exchange.dws'関数を含むワークスペースの名前(または、シェルが開いているのと同じディレクトリにファイルがない場合はパス)です。そのワークスペースファイルは、クリアなワークスペースを開き、入力し)ed apl_stock_farmer、上記のコードを貼り付けてから)save <path>。それが簡単であれば、このワークスペースファイルを提供することもできます。

-script これは、dyalogが指定されたコードを実行し、実際にREPLを開かずにstdoutに出力するようにする単なる引数です。

残念ながら、Windows CMDまたはPowershellで動作させる方法が見つからなかったため、Git Bashを使用して実行しました。このボットを競争に乗せることがどれほど実現可能かはわかりませんが、このコードを投稿しないのが好きです。


私がいないことを確認これは、競争に参加者として動作することですので、申し訳ありませんが、私は、Dyalog APLの未登録バージョンを持っている
ベータ崩壊

@BetaDecayわかりました、問題ありません。また、Pynaplライブラリを使用してこのコードを実行できることもわかりました。詳細は「PythonからAPLにアクセスする」、特に「Pythonを使用してtradfnを定義する」にあり、非常に簡単です。
J.サール

3

非識字配当投資家

import random
from sys import argv

price = float(argv[1])
shares = int(argv[2])
cash = float(argv[3])
round = int(argv[4])

# buy 1st round, sell last round
if round == 1:
    print('b' + str(int((cash + 1000) / price)))
elif round == 1000:
    print('s' + str(shares))

# round right before dividend: sell
elif round % 5 == 4:
    print('s' + str(shares))

# 1 round after dividend: buy
elif round % 5 == 0:
    print('b' + str(int((cash + 1000) / price)))

# 2 rounds after dividend: 50/50 sell/try to buy
elif round % 5 == 1:
    if random.random() < 0.5:
        print('s' + str(shares))
    else:
        print('b' + str(int((cash + 1000) / price)))

# 3 rounds after dividend: sell if own shares (didn't sell last round), else buy
elif round % 5 == 2:
    if shares > 0:
        print('s' + str(shares))
    else:
        print('b' + str(int((cash + 1000) / price)))

# otherwise, 4 rounds after dividend, buy
else:
    print('b' + str(int((cash + 1000) / price)))

配当後、人々はより多くの現金を持っていると仮定するので、彼らは購入する可能性が高くなります。配当の直前に売り、直後に買います。他の3ラウンドで、他の1つの売り/買いサイクルを通過します。


コントローラーを見ると、配当は5ラウンドごとだけでなく、4ラウンド以降のすべてのラウンドで支払われます。サイクルは引き続き機能するはずですが、おそらく意図したとおりではありません。
ヴェスカ

他の人が購入した後に購入すると、より高価なときに購入することになります。
fəˈnɛtɪk

ありがとう@Veskah。一部のr1 / r1000ロジックも追加する必要がありました。
brian_t

@ fəˈnɛtɪk-人々が配当後にラウンドを購入すると仮定すると、あなたもそのラウンドを購入してから販売したいでしょうか?
-brian_t

また、4回目以降は毎ラウンド配当を受け取るため、配当後のラウンドはありません。
-fəˈnɛtɪk

3

可能な限り購入/再投資してください!

驚いたことに非常に平均的だった私のドル・コスト・アベレージャーと同様に、これは各ラウンドを手頃な価格でできるだけ多く購入し、最後のラウンドでのみ販売します。

from sys import argv

share_price = int(argv[1])
share_count = int(argv[2])
balance = float(argv[3])
round = int(argv[4])


if round < 1000:
    if balance > share_price-1000:
        buy_count = int((balance+1000)/share_price)
        print("b"+str(buy_count))
    else:
        print("b0")
else:
    print("s" + str(share_count))

ねえ、ここでのインデントにエラーがあります。if balance > share_price-1000:ブロックをインデントするつもりでしたか?
ベータ崩壊

はい。私のマイナーな編集が​​私のフォーマットを混乱させたようです。PCに戻ったらすぐに修正します
Barbarian772

2

初心者ブローカー(ただし、基本的な考え方は理解できます)

se_stock_exchange.rb

DATA_FILE = $0.sub /\.rb$/, ".data"
NUM_ROUNDS = 1000

share_price, num_shares, money, round = ARGV.map &:to_i

order = "s0"

if round == NUM_ROUNDS
  puts "s#{num_shares}"
  exit
end

if File.exists? DATA_FILE
  last_price, trend, bought_price = File.read(DATA_FILE).lines.map &:to_i
else
  last_price = 0
  trend = -1
  bought_price = 0
end

if (new_trend = share_price <=> last_price) != trend
  case trend
  when -1
    order = "b#{(money + 1000) / share_price}"
    bought_price = [bought_price, share_price].max
  when 1
    if share_price > bought_price
      order = "s#{num_shares}"
      bought_price = 0
    end
  end
  trend = new_trend
end

File.open(DATA_FILE, "w") { |f| f.puts share_price, trend, bought_price }

puts order

価格が反転するまで待機してから、すべてを購入/販売します。つまり、Dummy for Dummies でそれがそうするように言っているということです。

にデータを保存しますse_stock_exchange.dataruby se_stock_exchange.rb ${SHARE_PRICE} ${SHARES} ${MONEY} ${ROUND}(適切な値に置き換えて)を実行します。


これはKotHでの最初の刺し傷ですので、間違っているかどうかを教えてください。
モニカiamnotmaynardを


このエラーが発生します:se_stock_exchange.rb:24:in `<main>': undefined method `+' for nil:NilClass (NoMethodError)
エリックアウトゴルファー

4
@BetaDecay:作者のミドルネームが「A」で始まらないのは残念です。
3D1T0R

3
@NieDzejkob:「A」の場合:「Ann A. Logue」は「Analog」に類似しています。
3D1T0R

2

ハーフモアオアナッシング

def run(price, shares, balance, cur_round):
    if cur_round==1000:
        print('s'+str(int(shares)))
        return

    if cur_round==1:
        with open('HalfMoreOrNothing.dat', 'w') as f:
            f.write(str(int(price)))
        print('b'+str(int((balance+1000)/price)))
        return

    if shares==0:
        with open('HalfMoreOrNothing.dat', 'w') as f:
            f.write(str(int(price)))
        print('b'+str(int((balance+1000)/price)))
        return

    with open('HalfMoreOrNothing.dat', 'r') as f:
        bought_price=int(f.read())
    if price>=bought_price*1.5:
        print('s'+str(int(shares)))
        return

    print('b0')

if __name__ == '__main__':
    import sys
    run(*[float(x) for x in sys.argv[1:]])

私はめったにPythonを使用しません。これがどこかでエラーを生成するかどうかを教えてください。

戦略は、株価がバイイングの時点での価格より少なくとも50%大きくなるまで待ってから売却し、すぐに新しい株式を購入して、新しい株価の上昇を待つことです。

うまくいけば、人々のチンパンジーが終わり近くに株を売り始めないだろう...


2

フィボナッチ

物事を簡単にするために、これをPython 3で書き直しました。うまくいけば!

import math
from sys import argv

price = float(argv[1])
shares = int(argv[2])
balance = float(argv[3])
roundNum = int(argv[4])

fibonacci = [2,3,5,8,13,21,34,55,89,144,233,377,610,987]
if (roundNum == 1):
    buy = int((balance+1000)/price)
    print('b' + str(buy))
elif (roundNum in fibonacci) and roundNum % 2 == 1 and balance > 0:
    buy = int((balance/price)/2)
    print('b' + str(buy))
elif ((roundNum in fibonacci) and roundNum % 2 == 0) or roundNum % 100 == 0:
    if (roundNum == 1000):
        sell = shares
        print('s' + str(sell))
    else:
        sell = math.ceil(shares/2)
        print('s' + str(sell))
else:
    print('b0')

ラウンドがフィボナッチ数の奇数に等しい場合に手頃な最大株の半分を購入し、ラウンドがフィボナッチ数に等しく、100ラウンドごとに利用可能な株式の半分を販売します。ラウンド1000ですべての株式を売却します。それ以外の場合は、待機します。残高がプラスの場合にのみ株式を購入します。


ちょっと、エラーが発生しましたError in roundNum%%2 : non-numeric argument to binary operator Execution halted
ベータ崩壊

@BetaDecayこの問題を修正する可能性のあるコードを更新しました。お知らせ下さい。
ロバートS.

1

貪欲なB ***** d

# Gready one...
from sys import argv

SMA_PERIOD = 5
LAST_BUY_DAY = 985
LAST_SELL_DAY = 993

# Save an entry to the stock history
def save_history(price):
    with open('db.txt', 'a') as f:
        f.write(str(price) + '\n')

# Load the stock history
def load_history():
    with open('db.txt', 'r') as f:
        return [float(line.strip()) for line in f]

def get_sma(d, n):
    l = d[-n:]
    return int(sum(l) / len(l))


def buy(price, account):
    if account + 1000 > 0:
        print 'b' + str(int((account + 1000) / price))
        return
    print 'b0'

def sell(holdings):
    print 's'+ str(int(holdings))


def run(price, holdings, account, day):

    save_history(price)
    d = load_history()

    if price <= get_sma(d, SMA_PERIOD) and day < LAST_BUY_DAY:
        return buy(price, account)

    if price > get_sma(d, SMA_PERIOD):
        return sell(holdings)

    if day >= LAST_SELL_DAY:
        return sell(holdings)

    # Otherwise, do nothing    
    print 'b0'


run(*map(float, argv[1:]))  

彼はその安い時にすべてに行き、価格が上がるとそれをすべて売るでしょう...


あなたのコードはいたるところにあります。まず、あなたはprint文を返すだけでなく、あなたがする三つの引数渡しsell()のみが1とる
ベータ崩壊を

sell()する3つの引数を持つTypo ...印刷文を返す際の懸念は?
アレックS

不要だということ
ベータ崩壊

読みやすさを助けると主張する人もいます
Arek S

プリントのために結果に含めなかったのですか?afaik typo in sale()定義が動作を停止することはありません...
ところで

1

テクニカル分析ロボット

私はビジネス経済学を勉強しているので、株式市場を分析するための最も簡単な方法(テクニカル分析)を実現しようとしました。理論によると、グラフのすべての最小値を分析して、トレンド(上下)があるかどうかを確認する必要があります。上昇トレンドの間は購入する必要があり、下降トレンドの間は販売する必要があります。

この方法がうまく機能するとは思いませんが、試してみましょう:)

import sys
from sys import argv

share_price = int(argv[1])
share_number = int(argv[2])
bank_account = float(argv[3])
round_number = int(argv[4])

max_buy_greedily = (1000 + bank_account) / share_price
minima = []

def log():
    f = open("log_technical_analysis.txt","a+")
    f.write("%d;" % share_price)

def analyze():
    f = open("log_technical_analysis.txt","r+")
    line = f.readline()
    values = line.split(";")
    values.pop()
    for i in range(len(values) - 1):
        if i > 0 and int(values[i-1]) > int(values[i]) and int(values[i+1]) > int(values[i]):
            minima.append(int(values[i]))
    if len(minima) >= 3 and minima[len(minima) - 1] > minima[len(minima) - 2] and minima[len(minima) - 2] > minima[len(minima) - 3]:
        print('b' + str(int(max_buy_greedily)))
    elif len(minima) >= 3 and minima[len(minima) - 1] < minima[len(minima) - 2] and minima[len(minima) - 2] < minima[len(minima) - 3]:
        print('s' + str(share_number))
    else:
        print('b0')

if round_number >= 994:
    print('s' + str(share_number))
    sys.exit(0)

if share_price <= 15:
    print('b' + str(int(max_buy_greedily)))
    log()
    sys.exit(0)

log()
analyze()
sys.exit(0)

python3でテスト済み


2
幸運を!これは通常の市場から遠く離れている:D
ベータ崩壊

1
@BetaDecay haha​​ yeah:]しかし、ほとんどの人が株式市場(またはビットコイン)でお金をどのくらいランダムに使っているのか不思議に思うでしょう:D
Solenya

1

ラッキーナンバー6

編集:ああ、販売数をintに変換しないことが私の問題の1つだったと思います。

おそらく私の最後の貢献は、仕事に飽きて何かもっと洗練されたものにしない限りですが、洗練されたボットがすでにニッチを埋めるようになりました。

この男は基本的に6ラウンドごとに分け前の一部を売っています。なぜなら、ちょっと6が彼の幸運な数字だからです。

from sys import argv
import random

share_price = int(argv[1])
share_count = int(argv[2])
balance = float(argv[3])
round = int(argv[4])
x = random.uniform(1,2)

if round == 1 or round == 1000:
    print("s"+str(share_count))
elif round % 6 == 0 and share_price >= 10:
    sell = int(share_count/x)
    print("s"+str(sell))
elif balance > share_price-1000:
    buy_count = int((balance+1000)/share_price)
    print("b"+str(buy_count))
else:
    print("b0")
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.