스택 교환 증권 거래소-V3


42

주의 사항 : 이 과제는 이제 종료되었습니다. 리더 보드를 더 이상 업데이트하지 않으며 수락 된 답변을 변경하지 않습니다. 그러나 원하는 경우 컨트롤러를 실행하고 리더 보드를 직접 업데이트 할 수 있습니다.

채팅에 참여하십시오!

소개

좋은 저녁입니다, 상인들! 당신은 골프 회사 PPCG의 모든 상인입니다. 당신의 임무는 가능한 한 많은 돈을 버는 것입니다.

도전

가능한 많은 돈을 벌기 위해 Stack Exchange Stock Exchange에서 주식을 사고 파는 프로그램을 작성하십시오.

게임 플레이

모든 플레이어는 자신의 은행에서 5 주와 100 달러로 시작합니다. 게임은 항상 10 달러의 주가로 시작합니다.

각 게임에는 첫 라운드가 라운드 인 1000 라운드가 있습니다 1. 각 라운드에서 프로그램은 현재 주가, 보유한 주식 수, 소유 한 금액 및 라운드 수 (1 인덱스)의 네 가지 인수를 입력으로 제공합니다.

예를 들어, 내 프로그램이 test1.py이면 주가는 100, 보유한 주식 수는 3, 보유 하고있는 금액은 1200이고, 라운드 수는 576이면 프로그램은 다음과 같이 실행됩니다.

python test1.py 100 3 1200 576

한 라운드에서 각 플레이어에게 제공되는 주가는 동일합니다. 라운드가 끝날 때까지 변경되지 않습니다.

이에 대한 응답으로 플레이어는 자신의 명령을 인쇄해야합니다. 두 가지 옵션이 있습니다.

  • 구매 주 :이 명령은 다음과 같이 주어진다 bn어디 n당신이 구매하고자하는 주식의 수입니다. 예를 들어 100 주를 구매하려는 경우 다음을 출력합니다.
b100

주식을 구입할 때 최대 $ 1,000의 초과 인출이 허용됩니다. 이 초과 인출을 초과하는 충분한 주식을 구매하려고하면 (은행 잔고가 $ -1000 이하로 떨어짐) 파산으로 선언됩니다. 즉, 모든 주식을 잃게되고 잔액은 $ 50로 설정됩니다.

파산하더라도 주식 가격은 귀하의 명령에 영향을받지 않습니다.

(잔액이 $ -1000이면 파산되지 않습니다. 그러나 잔액이 $ -1001이면 파산합니다)

  • 주식 판매 :이 명령은 판매하고자하는 주식의 수를 나타내는 snn입니다. 예를 들어 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

마지막으로 순위표를 인쇄하고 게임 전체에서 주가가 어떻게 변했는지에 대한 그래프를 표시합니다.

예를 들어, 두 개의 임의 봇이 재생되었을 때

승리

마지막 게임이 끝날 때 잔액이 가장 많은 플레이어가 승리합니다.

리더 보드

게임 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

각 참가자의 그래프보기


관련이 있지만 게임 플레이 및 승리 기준은이 도전과 매우 다릅니다.


의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
Dennis

나를 위해 수식은 [Math Processing Error] 로 빨간색으로 표시됩니다. 다른 사람들도 마찬가지입니까? 그렇다면 질문에 문제가있을 수 있습니다.
Captain Man

2
행운의 영향을 줄이기 위해 10-100 게임보다 결과를 평균화하는 것이 좋습니다. 아니면 어쩌면 그것은 도전을 너무 많이 바꿀 것입니다.
mbrig

1
점수가 log2 / log10이 될 수 있습니까? 점수를 비교하는 것이 훨씬 쉬울 것입니다. (내 전화로 찾아 보니 지수가 화면에서 사라졌습니다)

1
나는 10-100조차도 너무 적다고 생각하지만 많은 게임을 좋아합니다 . 이를 가능하게하려면 현재 적용 범위를 벗어난 챌린지 형식을 변경해야합니다.
Nathan Merrill

답변:


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주석 처리를 제거해야합니다 (줄 시작시 세미콜론은 제거되지 않은 경우 제거해야 함).
    • ; extension_dir = "ext"
    • ;extension=gmp

1
와, 그 링크 주셔서 감사합니다! 궁금해했다 : D
베타 부패

1
@BetaDecay : 문제 없습니다. btw로 설치를 확인하는 2 단계 (PHP 테스트가 설치됨)까지만 진행하면됩니다 php -v. 나머지는 이것에 필요하지 않습니다. 이 도전을 위해 많은 다른 언어를 설정하는 데 많은 어려움을 겪을 것입니다! 나는 이런 식으로 절대 감히하지 않을 것입니다 : D
Night2

@BetaDecay는 TryItOnline을 Docker 컨테이너로 설치하는 것이 쉽지 않을까요?
NieDzejkob

@NieDzejkob 아마도 이러한 언어를 설치하는 것이 편리 할 것입니다.
Beta Decay

1
축하합니다, 당신은 지속적으로 다른 모든 참가자를 이겼습니다!
Beta Decay

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
더 똑똑 할 수도 있지만 더 운이 좋습니까?
Woohoojin

내 모든 테스트에서이 테스트가 시작되었습니다. 예
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에 오신 것을 환영합니다!
Beta Decay

감사합니다! 처음 게시 할 수있는 내용이 있으면 알려주세요.
just_browsing

마지막 라운드 investments에서 점수에 포함되지 않은 모든 주식을 판매하는 추가 조건을 추가 할 수 있습니다 .
Riking

2
그것이 OYAIB의 아름다움입니다. 자동으로 수행됩니다. target_cash는 "life"의 시점에 따라 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

@ Yakk 다른 사람들은 이미 테스트 실행에서 이것을 이겼습니다.
Outgolfer Erik

1 대 1? 나는 당황했다. 나는 가격 변동을 반전시키기에 충분한 부자가 될 수있는 방법을 알아낼 수 없으며 심지어 자원 더미를 태우지 않고 시간이 지남에 따라 규모가 커지는 것을 막을 수 없습니다 (LA는 희생을하지 않기 때문에 더 어려워집니다) 중지). LA가 일대일로 잃은 게임 플레이에 연결할 수 있습니까?
Yakk

@Yakk 아직 일대일 테스트하지 않았습니다. 또한 원하는 경우 토론 할 수 있는 대화방이 있습니다 .
아웃 골퍼 에릭

주식이 있고 가격이 이전 라운드보다 낮거나 돈이 있고 가격이 더 높은 경우 아무것도하지 않는 것이 더 강력합니까? 다른 유사한 봇과 동기화되지 않도록 보호합니다. 또한, 이것이 어떻게 일대일로 이길 수 있는지 보지 못합니다.
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 개의 주식을 팔아야한다고 생각합니다.
Kaldo

14
@ 칼도 나, 그는 그 시점까지 주식을 구입 한 번에 대해 오랫동안 잊어 버렸습니다
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

달러 비용 평균 기

(파이썬 3.7에서 테스트)

codegolf의 첫 번째 게시물이므로 잘못된 일이 있으면 알려주십시오.

기본 아이디어는 가능하면 매 라운드마다 주식을 하나 사서 마지막에 모든 주식을 판매하는 것입니다.

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 완료
Aidan F. Pierce

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'])num = str(random.randint(0, 1000000))?
Beta Decay

1
내가 게 으르니까
Skidsdev

1
왜 그렇게import lazy
우 후진

모든 것이 from random import randint, choice;print("{}{}".format(choice(["b", "s"]), randint(0, 1e6)));-P 로 줄어들 수 있음
Aaron F

6
예, 그러나 이것은 골프 도전이 아닙니다
Skidsdev

4

낮은 구매

(파이썬 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

대단한 도박꾼

(파이썬 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 파머

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

1 라운드에서 가능한 모든 주식을 매수하고 현재 주식 가격이 매수 가격보다 높은 경우에만 매도하는 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. Sallé

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 라운드에서 다른 판매 / 구매주기를 거칩니다.


컨트롤러를 살펴보면 배당금은 매 5 라운드뿐만 아니라 4 라운드마다 지불합니다. 사이클은 여전히 ​​작동하지만 의도 한대로 작동하지 않아야합니다.
Veskah

다른 사람이 구매 한 후에 구매하면 더 비쌀 때 구매하게됩니다.
fəˈnɛtɪk

감사합니다 @Veskah. r1 / r1000 논리도 추가해야했습니다.
brian_t

@ fəˈnɛtɪk-사람들이 배당 후 라운드를 구매한다고 가정하면 그 라운드를 구매하고 나중에 판매하고 싶습니까?
brian_t

네 번째 이후 매 라운드마다 배당금을 받으므로 배당 후 라운드도 없습니다.
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:블록 을 들여 쓰기 하시겠습니까?
Beta Decay

예. 사소한 편집으로 인해 형식이 중단 된 것 같습니다. 내가 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

가격이 돌아올 때까지 기다렸다가 모든 것을 사고 팔 수 있습니다. 나는 그것을에서 할 말씀의 그 말은 거짓에 대한 데이 트레이딩 이 아마 실제 책, 그리고 아마도 누군가가 그것에서 얻을 수 있습니다 뭔가 : 주 .

에 데이터를 저장합니다 se_stock_exchange.data. 로 실행합니다 ruby se_stock_exchange.rb ${SHARE_PRICE} ${SHARES} ${MONEY} ${ROUND}(적절한 값으로 대체).


이것은 KotH의 첫 찌르기이므로 내가 잘못하고 있는지 알려주세요.
iamnotmaynard


이 오류가 발생합니다 :se_stock_exchange.rb:24:in `<main>': undefined method `+' for nil:NilClass (NoMethodError)
Outgolfer Erik

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

파이썬을 거의 사용하지 않습니다. 어딘가에 오류가 발생하는지 알려주십시오.

전략은 주가가 소폭 순간 가격보다 적어도 50 % 커질 때까지 기다렸다가 매각 한 다음 즉시 새로운 주식을 사서 새로운 주식 가격 인상을 기다릴 수 있도록하는 것입니다.

다행스럽게도 사람들이 침팬지가 주식을 팔기 시작하지 않을 것입니다 ...


2

피보나치

일을 더 쉽게하기 위해 파이썬 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
Beta Decay

@BetaDecay 문제를 해결할 수있는 코드를 업데이트했습니다. 알려주세요.
Robert 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:]))  

그는 싼 때에 들어가서 가격이 올라가면 그것을 모두 팔 것입니다 ...


코드가 여기 저기 있습니다. 먼저, 당신은 인쇄 진술을 반환하지만 또한 당신 sell()은 단 하나를 취하는 세 가지 인수를 전달합니다
Beta Decay

sell ()에 대한 세 가지 인수가있는 오타 ... 이제 인쇄 명세서를 반환 할 때 어떤 문제가 발생합니까?
Arek S

불필요하다는 것
Beta Decay

일부는 가독성에 도움이된다고 주장
Arek S

인쇄 때문에 결과에 포함시키지 않았습니까? sale () 정의의 afaik 오타가 작동을 멈추지 않을 것입니다 ... 그건 그렇고 수정합니다
Arek S

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
Beta Decay

1
@BetaDecay haha ​​yeah :]하지만 대부분의 사람들이 주식 시장 (또는 비트 코인)에서 돈을 어떻게 쓰는지 궁금합니다. : D
Solenya

1

럭키 넘버 6

편집 : 오, ffs, 판매 카운트를 int로 변환하지 않는 것이 내 문제 중 하나라고 생각합니다. 여기서 다시갑니다.

직장에서 지루하지 않고 좀 더 정교하게 만들지 않는 한 아마도 마지막 기여 일 것입니다. 그러나 정교한 봇이 이미 틈새를 채우는 것처럼 떨어졌습니다.

이 사람은 기본적으로 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.