Stack Exchange Stock Exchange - V3
Chimps On A Typewriter
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))
Chimps are smarter than monkeys, they won't buy stocks they can't afford, or sell stocks they don't have.
Still pretty random otherwise though.
Run with python3, but should(?) work with python2 as well
The Experienced Greedy Idiot
PHP, tested on PHP >= 7, should work on previous ones as well.
<?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]);
An updated version of "The Greedy Idiot" with re-structured behavior and bug fixes related to working with huge numbers.
Notes:
- Save in a file and run it like this:
php C:\path\path\stack_exchange.php 10 5 100 1
- This script creates a text file with same name as the script file and a
.txt
appended to the end. So please run with an user with appropriate write permission on the script path. - A simple how to install PHP 7.2 on windows: http://www.dorusomcutean.com/how-to-install-php-7-2-on-windows/
- To work with super huge numbers, I had to use GMP, so these two lines on
php.ini
should be un-commented (the semi-colon at start of line should be removed, if it isn't already):; extension_dir = "ext"
;extension=gmp
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)
Following the old saying of "own your age in bonds," this program tries to do the same. This way we aren't subject to market volatility at the end-game.
Edit: Looking at the controller it shows that we can only buy/sell full shares, but can have a fractional account balance.