Sàn giao dịch chứng khoán Stack - V3


42

THÔNG BÁO: Thử thách này hiện đã kết thúc: Tôi sẽ không còn cập nhật bảng xếp hạng và sẽ không thay đổi câu trả lời được chấp nhận. Tuy nhiên, bạn có thể tự do chạy bộ điều khiển và tự cập nhật bảng xếp hạng nếu muốn.

Tham gia trò chuyện!

Giới thiệu

Chào buổi tối, thương nhân! Bạn là tất cả các thương nhân cho công ty golf PPCG. Nhiệm vụ của bạn là kiếm càng nhiều tiền càng tốt.

Thử thách

Viết chương trình mua và bán cổ phiếu trên Sàn giao dịch chứng khoán Stack với mục đích kiếm càng nhiều tiền càng tốt.

Trò chơi

Tất cả người chơi sẽ bắt đầu với 5 cổ phiếu và 100 đô la trong ngân hàng của họ. Trò chơi luôn bắt đầu với giá cổ phiếu là 10 đô la.

Mỗi trò chơi sẽ có 1000 vòng trong đó vòng đầu tiên là vòng 1. Trong mỗi vòng, chương trình của bạn sẽ được cung cấp bốn đối số làm đầu vào: giá cổ phiếu hiện tại, số cổ phần bạn nắm giữ, số tiền bạn sở hữu và số vòng (được lập chỉ mục 1).

Ví dụ: nếu chương trình của tôi là test1.py, giá cổ phiếu là 100, số cổ phần tôi nắm giữ là 3, số tiền tôi có là 1200và số tròn là 576, chương trình của tôi sẽ được chạy như vậy:

python test1.py 100 3 1200 576

Trong một vòng, giá cổ phiếu cho mỗi người chơi sẽ là như nhau. Điều này không thay đổi cho đến khi kết thúc vòng.

Để đáp lại, người chơi phải in lệnh của họ. Có hai lựa chọn:

  • Cổ phiếu Mua: Lệnh này được đưa ra như bnnơi nlà số lượng cổ phiếu mà bạn muốn mua. Ví dụ: nếu bạn muốn mua 100 cổ phiếu, bạn sẽ xuất ra:
b100

Khi mua cổ phiếu, bạn được phép thấu chi tối đa 1000 đô la. Nếu bạn cố gắng mua đủ số cổ phiếu vượt quá khoản thấu chi này (số dư ngân hàng của bạn dưới $ -1000), bạn sẽ bị tuyên bố phá sản. Điều này có nghĩa là bạn sẽ mất tất cả cổ phần của mình và số dư của bạn sẽ được đặt thành 50 đô la.

Giá cổ phiếu sẽ không bị ảnh hưởng bởi lệnh của bạn nếu bạn phá sản.

(Nếu số dư của bạn là $ -1000, bạn không bị phá sản. Tuy nhiên, nếu số dư của bạn là $ -1001, bạn bị phá sản)

  • Bán cổ phần: Lệnh này được đưa ra như snnơi nlà số lượng cổ phiếu mà bạn muốn bán. Ví dụ: nếu bạn muốn bán 100 cổ phiếu, bạn sẽ xuất ra:
s100

Bạn không thể bán nhiều cổ phiếu hơn bạn sở hữu. Nếu bạn cố gắng làm điều này, yêu cầu của bạn sẽ bị từ chối, và bạn sẽ bỏ qua vòng này.

Nếu bạn muốn bỏ qua vòng và không làm gì, hãy xuất b0hoặc s0.

Yêu cầu của bạn sẽ bị từ chối nếu bạn cố gắng mua hoặc bán một số lượng cổ phiếu âm và / hoặc số lượng cổ phiếu không nguyên.

Sau 5 vòng, vào cuối mỗi vòng, tất cả người chơi sẽ được trả cổ tức, giá trị bằng 5% giá cổ phiếu trung bình trung bình của 5 vòng cuối cùng.

Làm thế nào nó hoạt động?

Ban đầu giá cổ phiếu sẽ là 10 đô la. Vào cuối mỗi vòng, nó sẽ được tính toán lại bằng công thức:

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

Giá cổ phiếu sẽ được giới hạn để nó không bao giờ giảm xuống dưới $ 1.

Để ngăn thay đổi quá nhanh, thay đổi giá cổ phiếu được giới hạn ở mức tối đa là .±$200

Quy tắc

  • Chương trình của bạn phải có tên


  • Chương trình của bạn được cho phép một tệp văn bản duy nhất để lưu trữ dữ liệu. Nó phải được lưu trong cùng thư mục với chương trình của bạn


  • Bao gồm trong chi tiết câu trả lời của bạn về cách chạy chương trình của bạn


  • KotH này mở cho tất cả các ngôn ngữ lập trình miễn phí sử dụng và có thể chạy trên Windows 10


  • Điểm của bạn chỉ dựa trên nội dung số dư của bạn. Bất kỳ khoản tiền nào bị khóa trong cổ phiếu sẽ không được tính


  • Bạn có thể chỉnh sửa chương trình của bạn bất cứ lúc nào. Trước mỗi trò chơi, mã mới nhất sẽ được lưu và biên dịch


  • Bạn không nên viết mã mà cụ thể nhắm mục tiêu bot khác.

Bộ điều khiển

Bộ điều khiển được viết bằng Python và có thể tìm thấy ở đây: https://gist.github.com/beta-decay/a6abe40fc9f4ff6cac443395377ec31f

Cuối cùng, nó sẽ in bảng xếp hạng và hiển thị biểu đồ về cách giá cổ phiếu thay đổi trong suốt trò chơi.

Ví dụ, khi hai bot ngẫu nhiên đang chơi

Chiến thắng

Người chơi có số tiền cao nhất trong số dư của họ vào cuối trò chơi cuối cùng sẽ thắng.

Bảng xếp hạng

Trò chơi 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

Xem biểu đồ của từng thí sinh


Liên quan nhưng lối chơi và tiêu chí chiến thắng rất khác nhau đối với thử thách này.


Bình luận không dành cho thảo luận mở rộng; cuộc trò chuyện này đã được chuyển sang trò chuyện .
Dennis

Đối với tôi công thức hiển thị là [Lỗi xử lý toán học] màu đỏ. Nó có giống với những người khác không? Nếu vậy có lẽ đó là một vấn đề với câu hỏi.
Thuyền trưởng Man

2
Nó có thể có giá trị trung bình kết quả hơn nói, 10-100 trò chơi để giảm ảnh hưởng của may mắn. Hoặc có lẽ điều đó sẽ thay đổi thử thách quá nhiều.
mbrig

1
Có thể có điểm số là log2 / log10 không? Nó sẽ làm cho nó dễ dàng hơn nhiều để so sánh điểm số. (Tôi duyệt bằng điện thoại của mình và số mũ biến mất khỏi màn hình)

1
Tôi nghĩ rằng thậm chí 10-100 là quá ít, nhưng tôi thích chạy nhiều game. Để thực hiện điều đó, bạn cần thay đổi định dạng của thử thách, hiện không nằm trong phạm vi.
Nathan Merrill

Câu trả lời:


11

Kẻ ngốc tham lam có kinh nghiệm

PHP, được thử nghiệm trên PHP> = 7, cũng sẽ hoạt động trên các phiên bản trước.

<?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]);

Một phiên bản cập nhật của "Kẻ ngốc tham lam" với hành vi được cấu trúc lại và sửa lỗi liên quan đến làm việc với số lượng lớn.

Ghi chú:

  • Lưu trong một tệp và chạy nó như thế này: php C:\path\path\stack_exchange.php 10 5 100 1
  • Tập lệnh này tạo một tệp văn bản có cùng tên với tệp tập lệnh và được .txtthêm vào cuối. Vì vậy, vui lòng chạy với người dùng có quyền ghi thích hợp trên đường dẫn tập lệnh.
  • Cách đơn giản để cài đặt PHP 7.2 trên windows: http://www.dorusomcutean.com/how-to-install-php-7-2-on-windows/
  • Để làm việc với số lượng siêu lớn, tôi đã phải sử dụng GMP , vì vậy hai dòng php.ininày không được nhận xét (dấu chấm phẩy ở đầu dòng nên được loại bỏ, nếu chưa có):
    • ; extension_dir = "ext"
    • ;extension=gmp

1
Wow, cảm ơn vì liên kết đó! Tôi đã tự hỏi: D
Beta Decay

1
@BetaDecay: Không có vấn đề gì, btw bạn chỉ cần đi đến bước 2 (Kiểm tra PHP đã được cài đặt) nơi bạn kiểm tra cài đặt của mình php -v. Phần còn lại không cần thiết cho việc này. Tôi tin rằng bạn sẽ gặp nhiều rắc rối với việc thiết lập rất nhiều ngôn ngữ khác nhau cho thử thách này! Tôi sẽ không bao giờ dám làm điều gì đó như thế này: D
Night2

@BetaDecay sẽ không dễ dàng hơn nếu chỉ cài đặt TryItOnline làm bộ chứa Docker?
NieDzejkob

@NieDzejkob Có thể nhưng có thể sẽ có ích khi cài đặt các ngôn ngữ này
Beta Decay

1
Xin chúc mừng, bạn đã liên tục đánh bại mọi thí sinh khác!
Beta Decay

19

Tinh tinh trên một máy đánh chữ

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

Tinh tinh thông minh hơn khỉ, chúng sẽ không mua cổ phiếu mà chúng không đủ khả năng hoặc bán cổ phiếu mà chúng không có.

Vẫn còn khá ngẫu nhiên.

Chạy với python3, nhưng cũng nên (?) Hoạt động với python2


1
Họ có thể thông minh hơn, nhưng họ có may mắn hơn không?
Woohoojin

Trong tất cả các bài kiểm tra của tôi, bài kiểm tra này đã được đưa lên hàng đầu, vì vậy, có
Skidsdev

26
Tôi vô cùng tò mò làm thế nào điều này đã giành chiến thắng trong vòng đầu tiên với hơn 20 đơn đặt hàng lớn
mbrig

Tôi thích đặt nó xuống nghệ thuật của sự đơn giản. Mọi người khác đang quá kỹ thuật bot của họ.
Skidsdev

1
Điều này nhận được rất nhiều tình yêu, do nhầm lẫn: P
Night2

10

OYAIB

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)

Theo câu nói cũ "sở hữu tuổi của bạn trong trái phiếu", chương trình này cố gắng làm điều tương tự. Bằng cách này, chúng tôi không chịu sự biến động của thị trường vào cuối trò chơi.

Chỉnh sửa: Nhìn vào bộ điều khiển cho thấy chúng ta chỉ có thể mua / bán cổ phiếu đầy đủ, nhưng có thể có số dư tài khoản phân đoạn.


Chào mừng đến với PPCG!
Beta Decay

Cảm ơn bạn! Lần đầu tiên đăng bài để cho tôi biết nếu có bất cứ điều gì không đúng chỗ.
just_browsing

Bạn có thể muốn thêm một điều kiện bổ sung rằng vào vòng cuối cùng, bạn bán tất cả cổ phần của mình (như investmentskhông được tính vào điểm số của bạn).
Đạp xe

2
Đó là vẻ đẹp của OYAIB, nó tự động làm điều đó. Target_cash là một tỷ lệ phần trăm của Total_assets tùy thuộc vào điểm nào trong "cuộc sống". Vào cuối đời, target_cash là 100% của Total_assets, vì vậy nó sẽ bán bất kỳ cổ phiếu nào mà nó đang nắm giữ.
just_browsing

9

Kế toán đơn độc

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

Không lưu trữ bất cứ thứ gì trong buy-sell.txt.

Trong các vòng lẻ, nó mua càng nhiều cổ phiếu càng tốt. Trong các vòng chẵn, nó bán tất cả cổ phần của mình.

Mục đích trước tiên là tăng giá cổ phiếu bằng cách mua càng nhiều cổ phiếu càng tốt, sau đó bán số cổ phiếu đó để có thêm tiền. Nó hoạt động vì vòng cuối cùng là chẵn (vòng 1000).

Mặc dù giá cổ phiếu sẽ giữ nguyên ( 5) sau mỗi cặp vòng (giả sử bot chỉ có một mình, do đó, Lone Kế toán ), số dư của bot tăng lên, vì giá bán cao hơn giá mua và số dư nhiều hơn dẫn đến khả năng mua thêm cổ phiếu. Đó là một vòng luẩn quẩn, nhưng theo một cách tốt (đối với tôi).

Lỗ hổng lớn đi kèm với các bot độc ác chơi bên cạnh, bán để giảm giá cổ phiếu (không chắc nó có tốt cho họ không). Trong trường hợp này, bot có thể vẫn còn với số dư $ -890, miễn là có đủ bot ác. Kế toán này thực sự muốn sự yên tâm của họ. ;-)


1 trên 1 Tôi không chắc chắn nếu đánh bại điều này là có thể; không dễ chút nào ngay cả khi bạn hoàn toàn hiểu kế toán LA và cố gắng chống lại nó. Trong một trò chơi đại chúng, nơi bạn đông hơn bạn có thể bị vượt qua.
Yakk

@Yakk Những người khác đã đánh bại điều này trong các lần chạy thử của tôi.
Erik the Outgolfer

1 trên 1? Tôi bị bối rối; Tôi không thể tìm ra làm thế nào một đối thủ mà bạn có thể trở nên giàu có để đảo ngược sự dao động giá cả, hoặc thậm chí ngăn họ tăng trưởng theo thời gian mà không đốt cháy một đống tài nguyên (trong khi LA không hy sinh, vì vậy trở nên khó khăn hơn dừng lại). Bạn có thể liên kết với trò chơi mà LA mất một chọi một không?
Yakk

@Yakk Tôi chưa thử nó từng cái một. Ngoài ra, có một phòng trò chuyện để chúng tôi thảo luận về nó nếu bạn muốn.
Erik the Outgolfer

Sẽ không mạnh mẽ hơn nếu không có cổ phiếu và giá thấp hơn vòng trước hoặc bạn có tiền và giá cao hơn? Nó sẽ bảo vệ chống lại việc không đồng bộ với các bot tương tự khác. Ngoài ra, tôi không thấy làm thế nào điều này có thể được đánh bại từng người một.
JollyJoker

5

Nhà giao dịch thụ động

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

Anh chàng này không lớn trong toàn bộ "Cổ phiếu" này, nhưng anh ta nghe nói rằng nếu anh ta chỉ tiêu một ít tiền bây giờ, anh ta sẽ nhận được một ít tiền theo thời gian sẽ cộng lại nhiều hơn số tiền anh ta đã bỏ ra.

Anh ta sẽ mua đủ số cổ phiếu để về 0 đô la (không thấu chi cho người này, anh ta không phải là người mắc nợ vì một chút lợi nhuận), sau đó ngồi xung quanh để cho cổ tức được xây dựng

Chạy với python3, nhưng cũng nên (?) Hoạt động với python2.


1
Tôi nghĩ bạn nên bán ít nhất 15 cổ phiếu của mình trong vòng cuối cùng.
Kaldo

14
@Kaldo nah, từ lâu anh đã quên mất rằng anh đã mua cổ phiếu vào thời điểm đó
Skidsdev

5

Tỷ lệ phần trăm thương nhân Python3

(có thể hoạt động trong 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))

Hướng dẫn cách chạy

  • Lưu dưới dạng tên tệp
  • Chạy với python filename.py giá #shares số dư #

Làm thế nào nó hoạt động

  • Vòng đầu tiên bot mua càng nhiều cổ phiếu càng tốt.
  • Nếu giá tăng, bot bán một tỷ lệ phần trăm bằng với phần trăm tăng giá (tính từ giá trị mới)
  • Nếu giá giảm, bot mua một tỷ lệ phần trăm cổ phần tối đa mà nó có thể mua bằng với phần trăm giảm giá (tính từ giá trị trước đó)
  • Bán hết mọi thứ ở vòng 1000

Thay đổi hy vọng sẽ loại bỏ các vấn đề gây ra bởi phân chia dấu phẩy động


4

Thống kê Naïve

Tạo cho Python 3, có thể hoạt động trong 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:]))

Đây là một thống kê ngây thơ, cố gắng dự đoán giá cổ phiếu bằng cách chỉ mua / bán nếu giá tăng / giảm lâu hơn bình thường, trong khi cũng mua cổ phiếu nếu giá giảm xuống một và bán tất cả các cổ phiếu trong vòng cuối cùng.


4

Trung bình chi phí đô la

(đã thử nghiệm với Python 3.7)

Bài đăng đầu tiên trong codegolf vì vậy hãy cho tôi biết nếu tôi đã làm gì sai.

Ý tưởng cơ bản là mua một cổ phiếu mỗi vòng nếu có thể và bán tất cả cổ phiếu vào cuối.

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

Bộ cân bằng

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

Phân vùng nguồn tài chính của nó bằng nhau giữa tiền mặt và cổ phiếu trên mỗi vòng trừ vòng cuối cùng. Tôi tin rằng chiến lược này là một cách hợp lý để kiếm được ít nhất một số tiền, nhưng tôi có thể bị chứng minh là sai.

Có thể có hoặc không có lỗi mà tôi chưa bắt được. Cũng chơi golf phần nào.


Chương trình của bạn đang gặp khó khăn với số lượng lớn có liên quan ở đây, vì vậy tôi khuyên bạn nên thay đổi dòng p, n, b, r = map(float, argv[1:])thànhp, n, b, r = map(int, argv[1:])
Beta Decay

@BetaDecay đã hoàn thành
Aidan F. Pierce

4

Khỉ trên máy đánh chữ

import random

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

Đó là một đàn khỉ trên máy chữ. Bán ngẫu nhiên hoặc mua cổ phiếu X, trong đó:
0 <= X <= 1,000,000

Chạy với python3, nhưng cũng nên (?) Hoạt động với python2


4
Tại sao không sử dụng cmd=random.choose(['b','s'])num = str(random.randint(0, 1000000))?
Beta Decay

1
Bởi vì tôi lười biếng
Skidsdev

1
tại sao không chỉimport lazy
Woohoojin

toàn bộ điều có thể được giảm xuống from random import randint, choice;print("{}{}".format(choice(["b", "s"]), randint(0, 1e6)));-P
Aaron F

6
đúng, nhưng đây không phải là một thử thách golf
Skidsdev

4

Mua thấp

(Python 2 hoặc 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

Con bạc ngụy biện

(Python 2 hoặc 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

Nông dân APL (Dyalog)

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

Một TradFn mua mọi cổ phiếu có thể có trong vòng đầu tiên và chỉ bán khi giá cổ phiếu hiện tại cao hơn giá mà họ đã mua. Sau khi bán, bot sẽ chỉ mua cổ phiếu rẻ hơn giá bán cuối cùng của nó.

Đó là bởi vì kế toán của nông dân nói với anh ta rằng đó là cách bạn giao dịch chứng khoán. "Mua thấp, bán cao" và tất cả những thứ đó.

Khước từ

Đây là nỗ lực đầu tiên của tôi tại một thử thách KotH và vì về cơ bản tôi chỉ làm APL ở đây, tôi quyết định tiếp tục với nó.

Điều đó nói rằng, tôi không hoàn toàn chắc chắn liệu điều này có thể chạy được cùng với các bot khác hay không, vì nó là Tradfn và không thể được đưa trực tiếp vào vỏ CMD / Bash.

Vì vậy, để chạy cái này trong Bash, bạn cần có lệnh sau:

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

Ở đâu:

apl_stock_farmer là tên của hàm, nằm trong dòng mã đầu tiên.

argslà một vectơ của các đối số được phân tách bằng dấu cách (trong vòng đầu tiên, nó sẽ là 10 5 100 1).

dyalog là đường dẫn đến thực thi Dyalog

'stock_exchange.dws'là tên (hoặc đường dẫn, nếu tệp không nằm trong cùng thư mục, shell đã mở) của không gian làm việc có chứa hàm. Có thể lấy tệp không gian làm việc đó bằng cách mở một không gian làm việc rõ ràng, gõ )ed apl_stock_farmer, dán mã ở trên và sau đó thực hiện a )save <path>. Tôi cũng có thể cung cấp tệp không gian làm việc này nếu điều đó sẽ dễ dàng hơn.

-script chỉ là một đối số làm cho dyalog thực thi mã đã cho và in ra thiết bị xuất chuẩn mà không thực sự mở REPL.

Thật không may, tôi không tìm thấy cách nào để nó hoạt động với Windows CMD hoặc Powershell, vì vậy tôi đã chạy nó bằng Git Bash. Tôi không chắc khả thi của việc đưa bot này vào cuộc thi như thế nào, nhưng tôi thích cách mã này quá nhiều để không đăng nó.


Xin lỗi, tôi chỉ có phiên bản chưa đăng ký của Dyalog APL, vì vậy tôi không chắc chắn rằng điều này sẽ hoạt động như một người tham gia cuộc thi
Beta Decay

@BetaDecay Tôi hiểu, không có vấn đề gì ở đó. Tôi cũng phát hiện ra bạn có thể sử dụng thư viện Pynapl để chạy mã này. Các chi tiết trong phần "Truy cập APL từ Python", cụ thể là "Xác định giao dịch bằng Python" và nó trông khá đơn giản.
J. Sallé

3

Nhà đầu tư cổ tức không biết chữ

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

Giả sử sau khi chia cổ tức, mọi người có nhiều tiền mặt hơn, vì vậy họ sẽ có nhiều khả năng mua hơn. Bán ngay trước khi chia cổ tức, mua ngay sau đó. Đi qua một chu kỳ bán / mua khác trong 3 vòng còn lại.


Nhìn vào bộ điều khiển, cổ tức chi trả cho mỗi vòng sau vòng 4, không chỉ mỗi vòng 5. Chu kỳ của bạn vẫn sẽ hoạt động nhưng có thể không như bạn dự định.
Veskah

Nếu bạn mua sau khi người khác mua, cuối cùng bạn mua khi đắt hơn.
fnɛtɪk

Cảm ơn @Veskah. Phải thêm vào một số logic r1 / r1000 là tốt.
brian_t

@ fəˈnɛtɪk - giả sử mọi người mua vòng sau khi chia cổ tức, bạn cũng muốn mua vòng đó và sau đó bán, không?
brian_t

Cũng không có vòng nào sau cổ tức khi bạn nhận được cổ tức sau mỗi vòng thứ 4.
fnɛtɪk

3

Mua / Tái đầu tư càng nhiều càng tốt!

Tương tự như Trung bình chi phí đô la của tôi đã làm, thật đáng ngạc nhiên, khá trung bình, điều này mua mỗi vòng với số lượng cổ phiếu là phải chăng và chỉ bán chúng trong vòng cuối cùng.

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

Hey, bạn đã có một lỗi với thụt lề của bạn ở đây. Ý của bạn là thụt vào if balance > share_price-1000:khối hay không?
Beta Decay

Đúng. Chỉnh sửa nhỏ của tôi dường như đã phá vỡ định dạng của tôi. Sẽ khắc phục ngay khi tôi quay lại máy tính
Barbarian772

2

Novice Broker (nhưng có được ý tưởng cơ bản)

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

Chờ cho đến khi giá quay vòng, sau đó mua / bán mọi thứ. Ý tôi là, đó là những gì nó nói để làm trong Day Trading for Dummies Lưu ý: đây có lẽ là một cuốn sách thực sự và đó có lẽ là thứ mà ai đó có thể nhận được từ nó .

Lưu dữ liệu trong se_stock_exchange.data. Chạy với ruby se_stock_exchange.rb ${SHARE_PRICE} ${SHARES} ${MONEY} ${ROUND}(thay thế các giá trị thích hợp).


Đây là cú đâm đầu tiên của tôi vào KotH, vì vậy hãy cho tôi biết nếu tôi làm sai tất cả.
Tái lập lại Monica iamnotmaynard


Tôi nhận được lỗi này:se_stock_exchange.rb:24:in `<main>': undefined method `+' for nil:NilClass (NoMethodError)
Erik the Outgolfer

4
@BetaDecay: Thật tệ là tên đệm của tác giả không bắt đầu bằng 'A'.
3D1T0R

3
@NieDzejkob: Nếu đó là 'A': "Ann A. Logue" tương tự như " Analog ".
3D1T0R

2

Một nửa hoặc không có gì

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:]])

Tôi hiếm khi sử dụng Python, hãy cho tôi biết nếu điều này tạo ra lỗi ở đâu đó.

Chiến lược là đợi cho đến khi giá cổ phiếu lớn hơn ít nhất 50% so với giá tại thời điểm tạm biệt họ, sau đó bán chúng, sau đó mua ngay cổ phiếu mới để có thể chờ tăng giá cổ phiếu mới.

Hy vọng rằng, những con tinh tinh sẽ không bắt đầu bán cổ phiếu vào cuối ... (có vẻ như hầu hết các bot chỉ chờ đợi thời điểm thích hợp, bất kể đó là gì)


2

Tôi đã viết lại điều này trong Python 3 để làm cho mọi thứ dễ dàng hơn. Hy vọng!

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

Nó mua một nửa số lượng cổ phiếu tối đa có giá cả phải chăng khi vòng bằng một số Fibonacci lẻ và bán một nửa số cổ phiếu có sẵn khi vòng bằng với số Fibonacci chẵn và cứ sau 100 vòng. Bán tất cả cổ phiếu vào vòng 1000. Nếu không, nó chỉ chờ. Chỉ mua cổ phiếu khi số dư dương.


Xin chào, tôi gặp lỗiError in roundNum%%2 : non-numeric argument to binary operator Execution halted
Beta Decay

@BetaDecay Tôi đã cập nhật mã có thể khắc phục sự cố. Cho tôi biết.
Robert S.

1

Tham lam 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:]))  

Anh ta sẽ đi tất cả khi giá rẻ và bán tất cả khi giá tăng ...


Mã của bạn là tất cả các nơi. Đầu tiên, bạn trả về các câu lệnh in nhưng bạn cũng chuyển ba đối số sell()chỉ mất một
Beta Decay

Typo với ba đối số để bán () ... bây giờ bạn quan tâm gì với việc trả lại báo cáo in?
Arek S

Chỉ là chúng không cần thiết
Beta Decay

một số tranh luận họ giúp đỡ với khả năng đọc
Arek S

bạn đã không đưa nó vào kết quả vì bản in? Định nghĩa afaik typo in sale () sẽ không dừng hoạt động ... Tôi sửa nó bằng cách này
Arek S

1

Robot phân tích kỹ thuật

Tôi học kinh tế kinh doanh vì vậy tôi đã cố gắng nhận ra phương pháp đơn giản nhất để phân tích thị trường chứng khoán (phân tích kỹ thuật). Theo lý thuyết, bạn chỉ cần phân tích tất cả các mức tối thiểu của biểu đồ để xem liệu có một xu hướng (tăng thứ tự xuống). Trong một xu hướng tăng bạn phải mua và trong một xu hướng giảm bạn phải bán.

Tôi không nghĩ rằng phương pháp này sẽ hoạt động tốt nhưng hãy thử xem :)

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)

Đã thử nghiệm với python3


2
Chúc may mắn! Điều này khác xa với một thị trường bình thường: D
Beta Decay

1
@BetaDecay haha ​​yeah:] nhưng bạn sẽ tự hỏi làm thế nào ngẫu nhiên hầu hết mọi người tiêu tiền của họ trên thị trường chứng khoán (hoặc bitcoin): D
Solenya

1

Số may mắn 6

EDIT: Oh ffs, tôi nghĩ rằng tôi không chuyển đổi số lượng bán sang int là một trong những vấn đề của tôi, chúng ta lại bắt đầu.

Có lẽ là đóng góp cuối cùng của tôi, trừ khi tôi chán công việc và làm một cái gì đó tinh vi hơn một chút, nhưng tôi cảm thấy như những con bot tinh vi đã lấp đầy những ngóc ngách.

Anh chàng này về cơ bản bán một số cổ phiếu của mình sau mỗi 6 vòng, bởi vì hey 6 là con số may mắn của anh ta.

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")
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.