Trading Bot

Problem #397

Tags: finance challenge c-1 special simulation

This task has a Challenge attached.
You may View Stats or read a Help on Challenges.

No translations... yet
typical trading candle chart
Typical "Candle" chart showing recent price changes

Idea of making some easy money without both work and crime is appealing. In the past many people tried to do this via means of playing cards, but in our enlightened times we prefer trading! Buying and selling stocks, futures, currencies with hope of making profit. This sound so much more clever than cards!

Let us have a small experiment, to see whether this approach really is more clever - in other words, can it bring some stable profit. We'll use real market data of price changing over the course of few months - and your goal is to create small trading bot, which receives these data sequentially and should produce commands to buy or sell when needed.

General Concepts

We'll use data for BTC cryptocurrency price in relation to USD. You (or rather your "trading bot") receives update on price every 5 minutes (just in "fast-forward" fashion, of course). We'll use word tick for such five-minute periods. So after every "tick" your trading bot function is called with 4 values

Of course E of the preceding tick matches S of the next tick. H is greater or equal to any other while L is less or equal. At the picture above we see a candle chart which shows these ticks and represents all 4 prices for every tick. Each bar consists of "fat" middle part and optionally two "spikes" above and below it. These spikes show H and L price correspondingly, while S and E are marked by top and bottom of the "fat" part of the tick. Bar is green if S is below E and red otherwise.

You start trading with 1000 dollars. After each tick your trading bot analyses current prices and can make order. To keep things simple we mean by this "order to convert all your dollars to bitcoins". I.e. we always use whole budget and don't regard "margin trading" (in which you can trade for larger sums than you have, or can trade in expectation of price falling).

Money are converted according to E price (i.e. one existing at the moment when trading bot is observing the market). This is not pretty correct because actually money are not simply converted but some people are automatically matched who is willing to sell you BTC at this price - but we omit these details. Thus if you have $1000 and current tick ended with price 40000 you got 0.025 BTC.

If you have money converted to BTC (and thus no more USD at hand) - let us call this situation "order is open" (perhaps, not "order" but "position" in trading slang, but nevermind). In this situation the only command which your trading bot can make is to "close order". Money are converted back from BTC to USD also according to E price of the current tick.

For example, suppose price jumped to 40500 and converting your 0.025 BTC back you get 1012.50 USD. However exchange wants some profit for running this business so they take fee which is 0.1% of the money you have after closing - so actually you'll find about 1011.48 at your hands.

Of course if you close the order at price lower than it was opened, you are losing some money.

Stop-Loss and Take-Profit

As people, especially when trading manually, can't watch the market 24/7, there are two convenient features to creating order - namely, one can specify two prices at which order should be closed automatically:

Motivation

Market behavior is pretty stochastic because it relies on zounds factors, both natural and artificial. However it is different from situation if price would rise and fall completely at random (i.e. multiple factors is not the same as no factors). Market is actually driven by economical, social and political events - and also by specifics of participants behavior. Your trading bot can't receive and analyze information about economics and politics. However even capitalising on human behavior makes some sense. Suppose that due to (unknown) political and economical situation the price should be less or more stable for now. Still it shows some fluctuations. It is easy to imaging the following activities:

Thus the market may experience some "waves" of optimism and pessimism, which, while are not quite predictable, but may have some less or more defined characteristics. That's what we can try to profit from.

Disclaimer: even though we use real market data and your code may show some encouraging results, we don't recommend trying to make real business of it. This may be hazardous to your wealth. It should be understood that money are not popping out of nowhere - if someone wins in trading - these money are won from some other less lucky traders. Thus it is a kind of competition and the only true winner is of course exchange itself, which takes fee from every operation.

Problem Statement

You are to submit the function tick(...) written in Python (server runs PyPy 3.6.9) which works as trading bot. Here is an example:

def tick(s, h, l, e, order):
  import random
  if random.random() < 0.05:
    if order is None:
      return 'O'
    else:
      return 'C'
  return ''

The arguments to the function are the four prices as described above and order giving the price of the currently open order (or None). All prices are in cents (so they are integers).

Function may return either empty string (meaning "do nothing this time") or command to open / close the order.

Command to open the order is O [stoploss] [takeprofit] - i.e. capital letter O with optional one or two boundary prices, separated with one space each.

Command to close the order is simply C. If at the given tick both stoploss and takeprofit conditions are satisfied, the latter has preference (i.e. you got profit). If you send C command at the same tick when order was autoclosed, then autoclosing price has preference. Sending C when there is no order - and sending O when the order is already open - both result in error.

If the order is still open after the last tick of the whole interval, it is also forcibly closed there (i.e. as if user commanded C at last tick). Without it we can't calculate profit at all, of course.

Goal: try making at least 5% profit over the whole trading period. I.e. sum at your hands in the end should be at least $1050 for solution to be counted as successful and your result listed in the challenge table.

Sample Data - by this link you may find 3 fragments corresponding to 28 days each (also with 5m interval): https://github.com/CodeAbbey/data/blob/master/ca397-sample.txt click Raw or download button to get the file to your machine.

Short Example

Let us consider few ticks and bot's answers to them:

      function's input arguments           function's return value           what happened

   S       H       L       E    order
3456380 3495110 3443124 3488102 None                  ''
3488102 3499507 3401020 3401020 None                  ''
3401020 3433371 3350408 3375042 None                  'O'                    bought at 3375042
3375042 3389511 3314520 3321084 3375042               ''
3321084 3410040 3305223 3391971 3375042               'C'                    sold at 3391971
3391971 3441313 3352948 3382006 None                  ''
3382006 3429341 3365465 3369011 None                  'O 3200000 3450000'    bought at 3369011
3369011 3431931 3361818 3431931 3369011               ''
3431931 3464122 3431931 3464122 3369011               ''                     sold at TP=3450000
3464122 3470082 3442765 3460408 None                  ''

Here the bot executed two successful orders. The first was opened on the end of tick #3 and closed after the tick #5 which gave profit:

100000 * (3391971 / 3375042) = 100501

Which after subtracting 0.1% fee lefts 100401. Then the next order is opened after tick #7 and automatically closed by reaching "take-profit" price two ticks later, which gives:

100401 * (3450000 / 3369011) = 102814

Again this is reduced by fee to about 102712. There are some fractions not shown, but anyway we can declare overall profit about 2.7% made by the bot on these two orders.

You need to login to get test data and submit solution.