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.
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.
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
S
- price at start of the tickH
- highest price during the tickL
- lowest price during the tickE
- price at the end of the tickOf 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.
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:
stop-loss
price means that you want the order to be closed if the L
price on some tick in future falls below
this boundary - in other words you lose some money but you prevent potential greater lossestake-profit
price means that you want the order to be closed if the H
price at some future tick jumps
above this mark - you just grab some guaranteed profit not caring if price may rise even higherMarket 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:
BTC
BTC
tooBTC
backThus 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.
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.
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.