Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Background

You are all traders for a slightly less than reputable stock firm. You all are part of a group of traders who focus only on one specific stock.

Each hour each trader has a chance to Buy X stocks or Sell X stocks. There are 50 hours per round and 3 rounds per competition. At the end of all of the rounds the trader with the highest average value wins a trip to Jamaica!

Gameplay

There are 3 rounds of 50 turns each.

Each trader begins the round with $5000 and A random number of shares between 20 and 30 shares. The price of the shares starts at a random number between 10 and 150.

Each turn each trader can Buy any number of shares they can afford or Sell any number of shares they currently hold, each for the current price per share.

The price per share increases by a random number between 1 and 5 for each share bought and decreases by a random value between 2 and 6 for each share sold. The minimum price is $1.

It is important to note that all traders process their transactions at the same time, meaning that any trader buying/selling shares will not affect the price until the next turn.

The player with the highest average value at the end of the 3 rounds wins. Value is determined by taking the amount of money left over at the end of the round and adding the number of shares owned by the trader * closing market price.

Arguments

Your program will be rerun at the start of each turn receiving the current market price, the trader's current amount of money and the number of shares owned by that trader.

Ex:

120 5000 0

Output

Your trader program must output a letter corresponding to the action it would like to take followed by the quantity.

Ex:

B10 //Buy 10 shares

or

S3 //Sell 3 shares

The trader also has the option to not do anything that turn. That can be accomplished by outputting a W or any other command that is not 'B>amnt<' or 'S>amnt<'

Submissions

Your program will be inside a 'players/>your program name<' directory:

+-- players
|   +-- BotNameFolder
|       +-- BotProgram   

Please provide your code along with a command line argument to run it from inside the 'players' directory. For example the Test1 trader could be run with java -cp "Test1" Test1

Additional Rules

Go ahead, shoot yourself EmoWolf, Idc.

No messing with anything outside of your BotNameFolder directory, feel free to create files in there though for persistent info throughout rounds / turns.

Do not intentionally create programs to crash the simulation.

I will accept multiple entries per user, as long as the entries act as seperate entities (No insider trading).

Leaderboard

[java&-cp&"TestPlayer"&Test1]:$10027395221
[python&daydreamer/daydreamer.py]:$5000
[java&-cp&"DayTrader"&DayTrader]:$4713199930331196453

I will try to update the leaderboard at least once a day

Controller

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Random;


public class Controller {

    public static BigInteger marketValue = BigInteger.valueOf(100);
    public static BigInteger newValue = BigInteger.valueOf(100);

    public static final char BUY = 'B';
    public static final char SELL = 'S';

    public static final int MARKET_INDEX = 1;
    public static final int MONEY_INDEX = 2;
    public static final int SHARE_INDEX = 3;

    public static int numRunning = 0;
    public static final int MAX_RUNNING = 10;

    public static void main(String[] args){
        try {
            BufferedReader br1 = new BufferedReader(new InputStreamReader(new FileInputStream("resources/config")));

            int numRounds = Integer.parseInt(br1.readLine());
            int turnsPerRound = Integer.parseInt(br1.readLine());

            //Create the array of players
            List<String> players = new LinkedList<String>();
            String line1 = null;
            while((line1 = br1.readLine()) != null){
                players.add(line1);
            }
            BigInteger[] totalVals = new BigInteger[players.size()];
            for(int i = 0; i < totalVals.length; i++){
                totalVals[i] = BigInteger.valueOf(0);
            }
            br1.close();

            //Begin processing
            for(int round = 0; round < numRounds; round++){
                //Create players' shares and currency array
                Map<String,BigInteger[]> vals = new HashMap<String, BigInteger[]>();
                for(int i = 0; i < players.size(); i++){
                    vals.put(players.get(i), new BigInteger[]{BigInteger.valueOf(5000), BigInteger.valueOf(getRandInt(20,30))});
                }
                marketValue = BigInteger.valueOf(getRandInt(10,150));
                newValue = marketValue;
                for(int turn = 0; turn < turnsPerRound; turn++){
                    marketValue = newValue;
                    Queue<Object[]> processQueue = new LinkedList<Object[]>();
                    for(String playerKey : vals.keySet()){
                        BigInteger[] valSet = vals.get(playerKey);
                        String[] pkParts = playerKey.split("&");
                        String[] parts = new String[pkParts.length + 3];
                        for(int i = 0; i < pkParts.length; i++){
                            parts[i] = pkParts[i];
                        }
                        parts[pkParts.length] = marketValue + "";
                        parts[pkParts.length + 1] = valSet[0] + "";
                        parts[pkParts.length + 2] = valSet[1] + "";
                        processQueue.add(new Object[]{playerKey, parts});
                    }

                    while(!processQueue.isEmpty() || numRunning > 0){
                        if(numRunning < MAX_RUNNING && !processQueue.isEmpty()){
                            numRunning++;
                            Object[] o = processQueue.poll();
                            String pKey = (String)(o[0]);
                            String[] p = (String[])(o[1]);
                            try {
                                Process proc = new ProcessBuilder(p).directory(new File("resources/players").getAbsoluteFile()).start();
                                BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
                                String line = br.readLine();
                                br.close();
                                switch(line.charAt(0)){
                                case BUY :
                                    BigInteger numShares = new BigInteger(line.substring(1).trim());
                                    if(numShares.multiply(marketValue).compareTo(vals.get(pKey)[0]) <= 0){
                                        BigInteger[] tempVals = vals.get(pKey);
                                        tempVals[0] = tempVals[0].subtract(numShares.multiply(marketValue));
                                        tempVals[1] = tempVals[1].add(numShares);
                                        vals.put(pKey, tempVals);
                                        newValue = newValue.add(numShares.multiply(BigInteger.valueOf(getRandInt(0,2))));
                                        if(newValue.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) >= 1){
                                            newValue = BigInteger.valueOf(Integer.MAX_VALUE - 1);
                                        }
                                    }
                                    break;
                                case SELL:
                                    BigInteger shares = new BigInteger(line.substring(1).trim());
                                    if(shares.compareTo(vals.get(pKey)[1]) <= 0){
                                        BigInteger[] tempVals = vals.get(pKey);
                                        tempVals[0] = tempVals[0].add(shares.multiply(marketValue));
                                        tempVals[1] = tempVals[1].subtract(shares);
                                        vals.put(pKey, tempVals);
                                        newValue = newValue.subtract(shares.multiply(BigInteger.valueOf(getRandInt(5,10))));
                                        if(newValue.compareTo(BigInteger.valueOf(1)) <= -1){
                                            newValue = BigInteger.valueOf(1);
                                        }
                                    }
                                    break;
                                }
                            } catch (Exception e) {
                                System.err.println("[" + pKey + "] threw error:");
                                e.printStackTrace();
                            } finally{
                                numRunning--;
                            }
                        }else{
                            try{
                                Thread.sleep(50);
                                continue;
                            }catch(InterruptedException e){
                                continue;
                            }
                        }
                    }
                    System.out.println("Turn " + turn + " over: " + marketValue);
                }
                System.out.println("End of round market value is: " + marketValue);
                int count = 0;
                for(String player : vals.keySet()){
                    totalVals[count] = totalVals[count].add(vals.get(player)[0].add(vals.get(player)[1].multiply(marketValue)));
                    count++;
                }
                newValue = BigInteger.valueOf(100);
            }
            for(int i = 0; i < players.size(); i++){
                System.out.println("[" + players.get(i) + "]:$" + (totalVals[i].divide(BigInteger.valueOf(numRounds))));
            }
        } catch (Exception e) {
            System.err.println("An exception occured while running the controller.");
            e.printStackTrace();
        }
    }
    public static Random r = new Random(new Date().getTime());
    public static int getRandInt(int min, int max){
        return r.nextInt(max - min) + min;
    }
}

Compile this with java Controller.java and run from a directory containing a directory like below:

+-- resources
|   +-- config
|   +-- players
|       +-- Player1Folder
|           +-- Player1Program
|       +-- Player2Folder
|           +-- Player2Program

The file config should look something like this:

3
50
java&-cp&"TestPlayer"&Test1
python&daydreamer/daydreamer.py
java&-cp&"DayTrader"&DayTrader

First number is number of rounds, second number is turns per round, followed by the commands to run each player.

Replace spaces with ampersands! ('&')

~Let me know if I can improve the wording of this post at all, and happy trading!

share|improve this question
4  
It seems that the long-term trend in a busy market will see the share have a negative value. –  Peter Taylor Aug 20 at 15:47
5  
Could you put your controller program on something like Github and include a link so that we can test at home? –  Peter Taylor Aug 20 at 19:13
6  
Looking at the leaderboard, I think the game is currently flawed. E.g., start at $14/sh, buy 357 (own 357, $0 in bank). Choose random number (3). Price goes up by 3*357 to $1085/sh. Next round. Sell all 357 shares (own 0, $387,345 in bank). Choose random number (3). Price goes down by 3*357 to $14/sh. Next round. After two rounds, the price has not changed and your bank has increased 77x (similar but less dramatic results can be had with other starting random variables). I propose changing to for each transaction instead of for each share for more reasonable values. –  tolos Aug 20 at 20:28
3  
Or just build a real order book. –  Lohoris Aug 21 at 8:21
3  
Why start with a random num of shares? –  Averroes Aug 22 at 6:50

25 Answers 25

I present 'daydreamer', who is always asleep and forgets to buy or sell anything. He hopes that other players will have a net loss. Python code:

if __name__ == "__main__":
    print "W"

run with python daydreamer\daydreamer.py 120 5000 0 or whatever values you want.

I will post a more serious answer later, this is just to get the ball rolling :)

share|improve this answer
3  
I don't think that will run - you need to indent the print. –  isaacg Aug 20 at 16:50
    
thanks, fixed. was a typo during formatting –  stokastic Aug 20 at 17:52
6  
Given that the stock price will tend to drop in the long run, not trading may be an excellent strategy. –  Lego Stormtroopr Aug 21 at 4:04
4  
A strange game: the only winning move is not to play. How about a nice game of chess? –  Tim S. Aug 22 at 14:29

DayTrader

Updated for rule change made on 8/21/2014, where players now start with 20-30 shares.

Buys as much as possible, then sells as much as possible.

Philosophy

We hope that the below pattern will repeat itself over and over. Note that by adhering to this pattern, we also contribute to it.

  • Everyone can only buy or hold on round one. The value can only increase, so we buy.
  • Everyone can buy more, hold, or sell on round two. We don't expect many players to buy on round two, so we sell.

The pattern is crystal clear at the beginning. Value will increase after round one. It should decrease after round two. Beyond that, projections get fuzzy. I expect to do well in the early rounds, before the market stabilizes.

import java.math.BigInteger;

/**
 * Submission for http://codegolf.stackexchange.com/q/36515/18487
 * @author Rainbolt
 */
public class DayTrader {

    /**
     * @param args the command line arguments containing the current 
     * market value, our current money, and our current shares
     */
    public static void main(String[] args) {
        BigInteger marketValue = new BigInteger(args[0]);
        BigInteger myMoney = new BigInteger(args[1]);
        BigInteger myShares = new BigInteger(args[2]);

        // If we have less than or equal to 30 shares, buy as much as possible
        if (myShares.compareTo(new BigInteger("30")) <= 0) {
            System.out.println("B" + myMoney.divide(marketValue).toString());
        // Otherwise, sell as much as possible
        } else {
            System.out.println("S" + myShares.toString());
        }
    }

}

Compile with javac DayTrader.java. Run with java -cp "DayTrader" DayTrader.

share|improve this answer
1  
Yay java! Makes it easier for me to run. –  spocot Aug 20 at 17:26
6  
Your bot made market extend beyond the max number for integers, so I implemented BigIntegers into the code. Since everyone's code used ints, it crashed pretty much everyone's bot cept for the daydreamer –  spocot Aug 20 at 18:04
    
@spocot I edited my implementation to use BigInteger. Hopefully that helps. –  Rainbolt Aug 20 at 18:26
5  
I think this is an inherent problem in the rules. If one trader gets like 140 shares he could control the market by himself. In two rounds he can buy shares for 10 each and sell them for 140 each, leading to a win of 1300% (assuming nobody does the opposite). This will escalate to something like 5000 * 13^25, which is way to big. –  Optokopper Aug 20 at 18:50
2  
@spocot I just wanted to ping you because I modified my submission after your recent rule change. –  Rainbolt Aug 21 at 16:11

Walt Disney - Python 3

Walt waits until the shares hit rock bottom and then buys as much as his money allows. Then, when the price soars, he sells them all.

Based upon Disney's strategy when he 'survived' through the Wall Street Crash. Unfortunately, my program cannot build theme parks... If only...

Run:

python3 waltdisney.py

Code:

from sys import argv
import os

price=int(argv[1])
money=int(argv[2])
share=int(argv[3])

if os.path.exists('./buyingprice.txt'):
    f = open('buyingprice.txt', 'r')
    buyingprice=int(f.read())
    f.close()
else:
    buyingprice=0

if share > 0:
    if price > buyingprice*10:
        print('S'+str(share))
    else:
        print('W')
elif money > 0:
    if buyingprice==0:
        print('B10')
        m=open('buyingprice.txt', 'w')
        m.write(str(price))
        m.close()
    elif price <= buyingprice:
        print('B'+str(int(money/price)))
        g=open('buyingprice.txt', 'w')
        g.write(str(price))
        g.close()
    else:
        print('W')
share|improve this answer
    
You're missing a closing parenthesis on your first print line. –  supersam654 Aug 20 at 21:06
    
@supersam654 Oh yeah, thanks –  Beta Decay Aug 20 at 21:12
    
Can you point to a source for your assertion that Walt Disney actually used this strategy. Given there is a company named Walt Disney Co on the stock exchange it is difficult to search for, and Walt's wikipedia page doesn't mention it. –  Michael Aug 23 at 20:43
    
    
@Michael I got the information originally from my history teacher, so sorry if the source is a bit weak. –  Beta Decay Aug 23 at 22:52

Tommy

only knows what he has but is determined to risk everything on the market. If he can buy, he will. If he can't, he sells everything he has so he can next turn. (This will work well with extreme ones like DayTrader but will autocorrect if the value drops when he thinks it will grow.)

import java.math.BigInteger;

public class Tommy {
    public static void main(String[] args) {
        BigInteger Value = new BigInteger(args[0]);
        BigInteger Money = new BigInteger(args[1]);
        BigInteger Shares = new BigInteger(args[2]);

       if (Money.compareTo(Value)<1) {
           System.out.print("S" + Shares.toString());
       } else {
           System.out.print("B" + Money.divide(Value).toString());
       }
    }

}

Golfscript

This is the same code but if prefered this. I wrote the java after in case the BigInteger thing was needed. Use whatever is easier.

2$2$>{@@;;"S"\}{;\/"B"\} if
share|improve this answer
    
For future reference, all numbers in GS are big integers. –  Peter Taylor Aug 21 at 12:39
    
I guess I could have just posted the original without worrying about it then! Good news. –  kaine Aug 21 at 13:04
    
I originally commented that I thought this was a duplicate of DayTrader, but then I realized that the behavior is only the same because of circumstances, and that they could diverge under other circumstances. Sorry if I offended anyone. Let's get rich together! –  Rainbolt Aug 21 at 14:41
    
@Rainbolt I wrote it GolfScript, read yours looking for duplicates before submitting, and actually used some or your code to write the Java version. The core part is not a duplicate (or I wouldn't have submitted it) but ends up being simular in these volitile markets. I'm not offended but if you feel it is too close I will request it be disqualified (but the code remain, I learned something writing it which is the whole point). As you have priority I wouldn't be offended even in that case. Note Earthquakers is almost identical to yours but does it differently (saves to file). –  kaine Aug 21 at 15:04
    
@kaine No no don't delete it. Like I said, I thought they were duplicates, but they definitely aren't. They are similar in behavior only because of the circumstances. I was wrong to post a comment claiming they were duplicates before I fully understood what yours was doing. –  Rainbolt Aug 21 at 15:06

The NSA - GNU/Unix Utilities

The NSA knows how the stock markets are going to move and they've used the knowledge to insert a backdoor into sha encryption. We exploit this to gain a competitive advantage.

egrep -o '[bc][0-9]+' <<< $(sha512sum <<< $@) | sed "s/c/S/;s/b/B/" | head -1

Run with

bash nsa.sh arg argh aarrrggh

It's also super error-tolerant.

share|improve this answer
5  
Aaaarrrrrgggghhh! –  Doorknob 冰 Aug 22 at 15:38

BuyAndHold - C

#include <stdio.h>
#include <stdlib.h>

/* BuyAndHold
 * Code revised from OptoKopper's WaitForCrash.c
 */
int main(int argc, char *argv[]) {
    long long int share_price = strtoll(argv[1], NULL, 0);
    long long int money = strtoll(argv[2], NULL, 0);

    if (money >= share_price) {
        printf("B%lld\n", money / share_price);
    } else {
        printf("W\n");
    }

    return 0;
}

Compile with: gcc buyandhold.c -o buyandhold

Run it with ./buyandhold PRICE MONEY SHARES

share|improve this answer
1  
Haha I was hoping someone would complement DayTrader with a BuyAndHold. Well done! –  Rainbolt Aug 20 at 18:41

Alfred Pennyworth - Python 2

While I was out on patrol one night, Alfred tried to create a stock trading program without my knowing. He thought he could hide it from me, but I found it and figured out what it did. Because I'm Batman. Now I've decided to enter it into a competition to teach him a lesson.

Money is no object to Alfred because I'm REALLY rich, but he's still smart about his trading. When he's out of shares, he buys as many as he can afford, regardless of market price. Then he sells 10 (or all remaining) shares every time the market price is higher than the price it was purchased at.

import argparse

parser = argparse.ArgumentParser(description="This is a private matter, Master Bruce. Learn how to make your own bed and I will tell you.")
parser.add_argument("Stuff", type=int, nargs='+', help="You don't need to know, Master Bruce.")

args=parser.parse_args()
vals=[]
for x in args:
    vals.append(x)

a=vals[0]
b=vals[1]
c=vals[2]

if c==0:
    x=1
    while x*a<b:
        x+=1
    print "B"+str(x)
    with open("lastval.txt", w) as f:
        f.write(a)

else:
    lastval=next(open("lastval.txt"))
    if a>lastval:print "S10" if c>10 else "S"+str(c)
    else:print 'W'

Run with: python GoAwayMasterBruce.py <args>

share|improve this answer
    
AttributeError: 'ArgumentParser' object has no attribute 'parseargs' Which version of Python does it need? –  Peter Taylor Aug 22 at 23:17
    
My mistake, there's an underscore. parse_args() –  Batman Aug 25 at 18:11

NaiveBot

NaiveBot is new to all this "stock market" hooplah. He just assumes that when the price is going up he should buy, and when the price goes down he should sell. But he's no sap, he's got a trick up his sleeve! He only ever buys half of what he can afford, and only ever sells half of what he has.

No more living in a box under the freeway for NaiveBot!

<?php
$cur = array('price' => $argv[1], 'funds' => $argv[2], 'shares' => $argv[3]);

$cachefile = 'cache.json';
if( ! file_exists($cachefile) ) { $cache = array(); }
else { $cache = json_decode(file_get_contents($cachefile), true); }

// determine action
if( empty($cache) ) {
    $action = 'buy'; // always buy on first turn
} else if( $cur['price'] > $cache[count($cache)-1]['price'] ) {
    $action = 'buy';
} else if( $cur['price'] < $cache[count($cache)-1]['price'] ) {
    $action = 'sell';
} else {
    $action = 'hold';
}

// determine volume
if( $action == 'hold' ) {
    $volume = 0;
} else if( $action == 'buy' ) {
    // spend half my money on shares!
    $volume = floor(($cur['funds']/2)/$cur['price']);
} else if( $action == 'sell' ) {
    // sell half my shares!
    $volume = floor($cur['shares']/2);
}

// do a thing!
if( $action == 'hold' ) { echo 'W'; }
else if( $action == 'buy' ) { echo "B $volume"; }
else { echo "S $volume"; }
echo "\n";

$cache[] = $cur;
if( count($cache) == 50 ) { unlink($cachefile); } // wipe cache on last turn
else { file_put_contents($cachefile,json_encode($cache)); } // write cache

Run with php Naivebot.php $1 $2 $3, makes a cache.json in its current folder.

share|improve this answer

Profit - Haskell

  1. Wait until the price is 1/maxValue
  2. Buy/Sell everything
  3. ????
  4. PROFIT!!!

import System.Environment (getArgs)

main = putStrLn . trade . map read =<< getArgs

trade :: [Integer] -> String
trade [p,m,s] -- not intended
  | p == 1 = "B" ++ (show m)
  | p == (fromIntegral $ (maxBound::Int) - 1) = "S" ++ (show s)
  | otherwise = "W"

Compile with ghc profit.hs and run with ./profit price money stock.

If it is not efficient enough, add -O3 flag, although it probably is overkill :D


Edit:

"optimised", now sells everything when the price is equal to Integer.MAX_VALUE.

share|improve this answer
    
Why not main = putStrLn . trade . map read =<< getArgs ? Less noisy –  recursion.ninja Aug 22 at 5:24
    
@awashburn Because I am not that well read regarding monads ;) –  ThreeFx Aug 22 at 6:16
    
I hope my comment helped you learn something new! –  recursion.ninja Aug 22 at 15:20
    
@ThreeFx there's a program for doing it, cabal install pointfree, now everyone will think you eat monads for breakfast. –  Sean D Aug 22 at 21:09
    
@SeanD Thanks, I'll have a look at it –  ThreeFx Aug 22 at 21:16

WaitForCrash

EDIT: fixed flaw in concept

EDIT: now using long long int

This is my first try. It behaves really simple and keeps one share to distinguish if it is the first round or a later one. In the first round nothing can be lost, so it buys shares. If it has shares it sells them. If eventually share prices drop to 10, it will buy again.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    long long int share_price = strtoll(argv[1], NULL, 0);
    long long int money = strtoll(argv[2], NULL, 0);
    long long int shares_owned = strtoll(argv[3], NULL, 0);

    if(shares_owned > 1) {
        printf("S%lld\n", shares_owned - 1);
    } else if (shares_owned == 0 || share_price == 10) {
        printf("B%lld\n", money / share_price);
    } else {
        printf("W\n");
    }

    return 0;
}

compile with: gcc waitforcrash.c -o waitforcrash

run it as ./waitforcrash PRICE MONEY SHARES

share|improve this answer
    
Hope you don't mind I swiped your code to use as the basis for the BuyAndHold solution. BTW with long long ints, %d needs to be %Ld to avoid warnings (or is it %lld? Neither gives me a warning). –  Glenn Randers-Pehrson Aug 20 at 19:26
    
It's okay. Yeah I had the %lld in my code, must have forgotten them in the update, ty. –  Optokopper Aug 20 at 19:56

Earthquaker

Alternates between buying everything and selling everything (but one). It doesn't really aim to win as much as it does disrupt everyone else.

using System;
using System.IO;

namespace Earthquaker
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length < 3)
                return;

            int stockPrice = int.Parse(args[0]);
            int money = int.Parse(args[1]);
            int stocks = int.Parse(args[2]);

            bool shouldBuy = true;

            if (stocks != 0)
            {
                StreamReader sr = new StreamReader("brain.txt");
                if (sr.ReadLine() == "B")
                    shouldBuy = false;
                else
                    shouldBuy = true;
                sr.Close();
            }

            if (shouldBuy)
                Console.Write("B" + (money / stockPrice));
            else
                Console.Write("S" + (stocks - 1));

            StreamWriter sw = new StreamWriter("brain.txt", false);
            sw.Write(shouldBuy ? 'B' : 'S');
            sw.Close();
        }
    }
}

Compile with csc Earthquaker.cs. Run with Earthquaker.

share|improve this answer
    
.Net has System.IO.File.ReadAllText and WriteAllText, so you can simplify your history tracking slightly. –  Peter Taylor Aug 21 at 7:18
    
This crashes if it doesn't find its brain.txt file. –  Peter Taylor Aug 22 at 23:27

MonkeyTrader (in JAVA)

There's a saying that monkeys are good traders. I make the proof. Decisions between "buy" and "sell" are totally random.

import java.math.BigInteger;
import java.util.Random;

public class MonkeyTrader {
    /**
     * @param args the command line arguments containing the current 
     * market value, our current money, and our current shares
     */
    public static void main(String[] args) {
        BigInteger marketValue = new BigInteger(args[0]);
        BigInteger myMoney = new BigInteger(args[1]);
        BigInteger myShares = new BigInteger(args[2]);
        Random random=new Random();

        switch (random.nextInt(2)) {
        case 0:
            System.out.println("B" + myMoney.divide(marketValue));
            break;
        case 1:
            System.out.println("S" + myShares);
            break;
        }
    }
}
share|improve this answer

IntelliTrader

1st round he will sell his shares if they're a good price: $80 or more. Then he will sell off if the price is the same or better than the last price he sold at, buy if the price is the same or lower than the last price he bought at.

IntelliTrader.java

import java.io.*;
import java.math.BigInteger;
import java.util.Properties;

public class IntelliTrader {

    private static final String ROUND_NUM = "roundNum";
    private static final String LAST_BUY = "lastBuy";
    private static final String LAST_SELL = "lastSell";
    private static final String FILE = "IntelliTrader/memory.txt";

    private Properties memory;
    private int roundNum;

    private IntelliTrader(Properties memory) {
        this.memory = memory;
        roundNum = new Integer(memory.getProperty(ROUND_NUM, "0"));
    }

    public String evaluate(BigInteger market, BigInteger money, BigInteger shares) {
        String command = "W";
        if (roundNum == 0) {
            if (market.intValue() > 80) {
                command = sell(market, shares);
            } else {
                command = buy(market, money);
            }
        } else {
            if (market.compareTo(new BigInteger(memory.getProperty(LAST_SELL, "0"))) >= 0) {
                command = sell(market, shares);
            } else if (market.compareTo(new BigInteger(memory.getProperty(LAST_BUY, "999999999"))) <= 0) {
                command = buy(market, money);
            }
        }
        return command;
    }

    private String buy(BigInteger cost, BigInteger money) {
        memory.setProperty(LAST_BUY, cost.toString());
        return "B" + money.divide(cost).toString();
    }

    private String sell(BigInteger cost, BigInteger shares) {
        memory.setProperty(LAST_SELL, cost.toString());
        return "S"+shares.toString();
    }


    public static void main(String[] args) {    
        BigInteger marketValue = new BigInteger(args[0]);
        BigInteger myMoney = new BigInteger(args[1]);
        BigInteger myShares = new BigInteger(args[2]);

        Properties memory = new Properties();
        try {
            memory.load(new FileReader(FILE));
        } catch (IOException e) {
            //ignore, file probably doesn't exist yet
        }

        int roundNum = new Integer(memory.getProperty(ROUND_NUM, "0"));
        if (roundNum > 49) {
            roundNum = 0;
            memory.setProperty(ROUND_NUM, "0");
            memory.setProperty(LAST_BUY, "0");
            memory.setProperty(LAST_SELL, "0");
        }

        IntelliTrader it = new IntelliTrader(memory);
        String command = it.evaluate(marketValue, myMoney, myShares);
        System.out.println(command);

        roundNum++;
        memory.setProperty(ROUND_NUM, ""+roundNum);
        try {
            memory.store(new FileWriter(FILE), "IntelliTrader memory properties");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Compile with javac IntelliTrader. Run with java -cp "IntelliTrader" IntelliTrader

share|improve this answer
    
In my tests this seems to be the second best trader. –  Peter Taylor Aug 23 at 7:08

theAnswerOfLifeIs42.py

My program loves the number 42

The rule is simple: I can either buy 42 stock or sell 42 stock.

import sys
price, money, shares = [int(arg) for arg in sys.argv[1:]]

if money>42*price:
 print "B 42"
else:
 print "S 42"
share|improve this answer

LeesonLearnt v1.1 (Java, conservative)

Since the rule change means that we now start with some shares, there's no longer a guaranteed best first move, so I've simplified this by removing the special case for the first turn.

import java.math.BigInteger;

public class LeesonLearnt {
    private static final BigInteger THRESHOLD = new BigInteger("100");

    public static void main(String[] args){
        BigInteger price = new BigInteger(args[0]);
        BigInteger capital = new BigInteger(args[1]);
        BigInteger shareholding = new BigInteger(args[2]);

        BigInteger affordable = capital.divide(price);

        // In the long run, the shares will probably lose all their value.
        // But if they're cheap, buying them will pump them and they can be sold at a profit.
        // The target amount of our value held in shares varies exponentially with their price.
        BigInteger targetShareholding = price.compareTo(THRESHOLD) > 0
            ? BigInteger.ZERO
            : affordable.add(shareholding).shiftRight(price.intValue() - 1);
        if (targetShareholding.compareTo(shareholding) <= 0) {
            System.out.println("S" + shareholding.subtract(targetShareholding));
        }
        else {
            BigInteger diff = targetShareholding.subtract(shareholding);
            System.out.println("B" + diff.min(affordable));
        }
    }
}

Invoke as

java -cp LeesonLearnt LeesonLearnt <price> <capital> <shareholding>
share|improve this answer

Dollar Cost Averager - Python 3

This strategy attempts to use dollar cost averaging by buying (as close as it can to) a fixed amount of money (arbitrarily set at 150 so that it'll probably use up most of its money by the end) each turn.

import sys
price, money, shares = [int(arg) for arg in sys.argv[1:]]
target_per_day = 150
buy = round(min(target_per_day, money) / price)
if buy * price > money:
    buy -= 1
if buy > 0:
    print("B" + str(buy))
else:
    print("W")
share|improve this answer

Cash Is King - Python 2 or 3

This guy is very pessimistic about the stock market. He'd rather keep his money in cash where he can keep it safe under his mattress.

import sys
shares = int(sys.argv[3])
if shares > 0:
    print("S" + str(shares))
else:
    print("W")
share|improve this answer

Slow and Steady

As long as it has money, it buys $165 worth of shares. Otherwise it sells all of its shares to get more money, to buy more shares. On the 50th round it makes sure to sell all shares, because in the end we want cash.

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Paths;

public class SlowAndSteady{
    public static void main(String[] args) {
        BigInteger price = new BigInteger(args[0]);
        BigInteger cash= new BigInteger(args[1]);
        long shares= Long.parseLong(args[2]);
        BigInteger number = new BigInteger("165");
        String count = "0";


        try {
            count = new String(Files.readAllBytes(Paths.get("counter.txt")));
        } catch (IOException e) {

        }

        int c = Integer.parseInt(count)+1;

        if (c >= 50)
        {
            System.out.println("S" + shares);
            c=0;
        }

        else if(cash.compareTo(number) > 0)     System.out.println("B" + (number.divide(price)));

        else System.out.println("S" + shares);


        try {
            Writer wr = new FileWriter("counter.txt");
            wr.write(Integer.toString(c));
            wr.close();
        } catch (IOException e) {
        }
   }
}

Compile with javac SlowAndSteady.java. Run with java -cp "SlowAndSteady" SlowAndSteady. Counter should reset between rounds, but if the file is deleted, it will also work.

share|improve this answer

BuyHighSellLow

Tracks the market history and buys when the price low and sells when it's high.

import sys

storage = 'BuyHighSellLow'
turn = 0
turns = 50
max_start_price = 150
limit = 0.25

price = int(sys.argv[1])
money = int(sys.argv[2])
shares = int(sys.argv[3])

# Calculate average price
with open(storage+'/history', mode='a') as f:
            pass # Create file if it doesn't exist
with open(storage+'/history', mode='r') as f:
    values = list((int(line) for line in f))
    turn = len(values) + 1
    if turn > turns: turn = 1
    if turn == 1:
            average = max_start_price + 1
            turn = 1
    else:
            average = sum((value / turn for value in values))

# Buy low and sell high
if price < average:
    print('B' + str(int(limit * money / price)))
elif price > average:
    print('S' + str(int(limit * shares)))
else:
    print('W')

# Save history
if turn == 1: mode='w'
else: mode = 'a'
with open(storage+'/history', mode=mode) as f:
    print(price, file=f)

Run with:

python3 BuyHighSellLow/buyhighselllow.py
share|improve this answer

Time is Right - Python 3

I got bored so I wrote another entrant...

This young entrepeneur lives his life by the clock. When the time is right, he makes a decision. He also annoyingly uses French out of context... ;)

Run:

python3 timeisright.py [arg1] [arg2] [arg3]

Code:

import sys, time

price = int(sys.argv[1])
money = int(sys.argv[2])
shares = int(sys.argv[3])

lheure = int(time.time())

if lheure % 3 == 0:
    print('S'+str(int(shares/4)))
elif lheure % 3 == 1:
    print('B'+str(int(money/4*price)))
else:
    print('W')
share|improve this answer

Ol' Timer - Fortran 77

This old man is going to waste away his pension after sixty years of working as an office clerk. During his old age, however, he became quite blind, so he can only see he first number of each argument, so he estimates the price. His method is similar to that of Walt's, except Ol' Timer is a little more careless.

Because of the problems with the Fortran printing, I've written a Python program which will help. The program takes the arguments supplied and pipes them through to the Fortran program. Then, the Python program reformats the output to the expected format.

Compile:

gfortran oltimer.for -o oltimer.exe

Run:

python3 assistant.py [arg1] [arg2] [arg3]

Python Assistant Code:

from subprocess import Popen, PIPE
import sys, re

ret = Popen('./oltimer.exe '+sys.argv[1]+' '+sys.argv[2]+' '+sys.argv[3], stdout=PIPE, shell=True).communicate()[0].decode('utf-8')
value=re.findall(r'\d+',ret)

if 'W' in ret:
     print('W')

elif 'B' in ret:
     print('B'+str(value[0]))

elif 'S' in ret:
     print('S'+str(value[0]))

FORTRAN Main Code:

      PROGRAM OLTIMER
C DEFINE VARIABLES
          INTEGER :: PRICE
          INTEGER :: STOCK
          INTEGER :: MONEY
          INTEGER :: INTBUFFER
          CHARACTER :: BUFFER
C GET CMD ARGUMENTS & CONVERT TO INT
          CALL getarg(1, BUFFER)
          READ (BUFFER, '(i10)') PRICE
          CALL getarg(2, BUFFER)
          READ (BUFFER, '(i10)') MONEY
          CALL getarg(3, BUFFER)
          READ (BUFFER, '(i10)') STOCK
C EVALUATE SITUTATION AND MAKE DECISION
          IF (PRICE.LT.5) THEN
            IF (MONEY.GT.0) THEN
                INTBUFFER=(MONEY*50)/(5-PRICE)
                PRINT*,'B',INTBUFFER
            ELSE
                PRINT*,'W'
            END IF
          ELSE
            IF (PRICE.GT.9) THEN
                IF (STOCK.GT.0) THEN
                    INTBUFFER=STOCK/(PRICE-9)
                    PRINT*,'S',INTBUFFER
                ELSE
                    PRINT*,'W'
                END IF
            ELSE
                PRINT*,'W'
            END IF
          END IF      
      END PROGRAM
share|improve this answer
1  
Given that you need Python anyway, and that there are other answers in Python but none in Fortran, do you not think it would make sense to implement the whole thing in Python and reduce the burden of compilers which OP has to install? –  Peter Taylor Aug 21 at 22:54
    
@Peter I would but I thought it'd be fun to have a completely different language and see how it performs. –  Beta Decay Aug 22 at 7:14

Test1 Trader

public class Test1 {

    public static void main(String[] args){
        int marketValue = Integer.parseInt(args[0]);
        int myMoney = Integer.parseInt(args[1]);
        int myShares = Integer.parseInt(args[2]);

        //Buy 10 if we don't have any.
        if(myShares <= 0){
            System.out.println("B10");
        }else{
            System.out.println("S1");
        }
    }
}

Compile with javac Test1.java run with java -cp "Test1" Test1

share|improve this answer

Hedgehog - python2.7

This is mostly to reserve the name

from __future__ import print_function
from sys import argv

storage = 'prices.txt'
price,cash,shares = map(long, argv[1:])
turn = 1
buy = lambda x: print('B%d' % long(x))
sell = lambda x: print('S%d' % long(x))
cashtoshares = lambda c: long(c/price)
TURN,PRICE,CASH,SHARES=range(4)

try:   
    data = [map(long, line.split()) for line in open(storage)]
    if data:
        turn = data[-1][TURN] + 1
except IOError:
    pass
with open(storage, 'a') as pricelist:
    pricelist.write('%d %d %d %d\n' % (turn, price, cash, shares))

if turn == 1:
    buy(cashtoshares(cash)) # convert all cash into shares
elif price == 1:
    buy(cashtoshares(cash)) # cannot buy at a better deal
elif price < 10:
    buy(cashtoshares(cash/2))
elif shares < 10:
    buy(cashtoshares(cash/2))
else:
    sell(shares/2)

Run as

python hedgehog.py PRICE CASH SHARES
share|improve this answer

BuyAndSell - C

Similar but not a duplicate of Tommy. Alternates between panic buying as much as possible and selling everything. Almost a duplicate of Earthquaker which retains one share while BuyAndSell sells all shares. BuyAndSell takes no action when it has no shares to sell but hasn't got enough money to buy one share.

/* BuyAndSell
 * Code revised from OptoKopper's WaitForCrash.c and my BuyAndHold.c
 * Alternates between buying as many shares as possible and selling everything
 * Run it as ./buyandsell PRICE MONEY SHARES
 */
int main(int argc, char *argv[]) {
    long long int share_price = strtoll(argv[1], NULL, 0);
    long long int money = strtoll(argv[2], NULL, 0);
    long long int shares = strtoll(argv[3], NULL, 0);

    if (money >= share_price) {
        printf("B%lld\n", money / share_price);
    } else {
        if (money == 0) {
            printf("S%lld\n", shares);
        } else {
            printf("W\n");
        }
    }

    return 0;
}

Compile with "gcc buyandsell.c -o buyandsell"

Run as "./buyandsell PRICE MONEY SHARES

share|improve this answer

Gorge Soros

price = ARGV.shift
money = ARGV.shift
stock = ARGV.shift
if price*10<money
  puts "B10"
else
  puts "S#{stock}"
end

Buys slowly, than sells everything in an attempt to crash the market.

Run with:Soros.rb price money stock

share|improve this answer
1  
It explicitly says in the question text Do not intentionally create programs to crash the simulation. –  Beta Decay Sep 1 at 17:25
    
@BetaDecay I meant dont try to crash the controller. Trying to crash the market is part of the game. –  spocot Sep 1 at 17:38
    
@spocot Oh, I thought that you meant to not create programs to crash the market. You should phrase that differently to prevent more confusion. –  Beta Decay Sep 1 at 17:46

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.