This document is intended for those who have successfully deployed the repository onto their own server, and would like to understand how to optimize towards profit.
To setup your poloniex account
- Sign up
- Go to
Balances > Deposits & Withdrawals
- Scroll to
[BTC] Bitcoin
- Get your deposit address.
- Send BTC to your deposit address.
- Note: You will need a way to get BTC. I use Coinbase, but YMMV.
- Wait until the transaction is confirmed.
To use your poloniex account with pytrader.
- Navigate to
[wrench] > API Keys
{screenshot} - Generate an API key that has "enable trading" set to true.
- Add your APIKey / Secret to your
pypolo/local_settings.py
file:
API_KEY = "<POLO_API_KEY>"
API_SECRET = "<POLO_SECRET>"
Here is the database model of the repository:
The core models, for optimization, are as follows:
- ClassifierTest - a wrapper around sklearn Classifiers, that runs a classifier to get a buy, sell, or hold, given a set of inputs (right now, a sample of price sequences, but in the future could include many other dimensions )
- PredictionTest - a wrapper around pybrain Supervised Learning functionality, that runs a neural network to get a predicted price, given a set of inputs (right now, a sample of price sequences, but in the future could include many other dimensions )
ClassifierTests and PredictionTests both have the following in common:
- take the same input.
- their output is (or can be interpreted as) as a buy/sell/hold.
- they are cheap to create, run, and store in the database (thanks to being django models)
ClassifierTests and PredictionTests differ in that:
- the former predicts a buy/sell/hold, the latter predicts a next price.
For reference, here are the UI views presently in the repo. They are linked in /admin
:
- Django admin
- Portfolio view - Reperesnts an overview of your portfolio.
- Trader optimizer - Gauges how reliable your trade.py configurations are at reprsenting the market.
- NN optimizer - Helps you pick which
PredictionTest
configurations to trade with. - Classifier optimizer - Helps you pick which
ClassifierTest
configurations to trade with.
In order to find configurations of Classifier/PredictionTests that are correct as often as possible (and wrong as little as possible), I have taken the approach of enumerating through as many possible permutations of configurations of each. For each configuration, I test against a sample input, and record how often this configuration was correct.
- The predict_many_sk.py management command enumerates through ClassifierTests, and outputs a percent_correct for each.
- The predict_many_v2.py management command enumerates through PredictionTests, and outputs a percent_correct for each.
Take a moment to look at the code for each of the above. I'll wait.
You're back? Cool -- So you've seen that each management command is basically a series of nested for loops, the sum of all of them is a brute force enumeration of each parameter.
NOTE: Both predict_many_sk, and predict_many_v2 are scheduled to run in the background. They can each take several hours to complete.
Run both ./manage.py predict_many_sk
, and ./manage.py predict_many_v2
. Come back after they've completed (a few hours depending upon how powerful your server is).
- Fire up a web browser, and point it to your local installation. Check out
admin/nn_charts
) or follow the link from the django admin. - You'll see something like this.
- Check out the table of contents to the right. Those are all of the parameters to your neural network.
- Note the metadata at the top of the control panel. Using this, you can see some statistical information about the
percent_correct
ness of your test runs. You can also change the ticker being viewed, or expand the search parameter for PredictionTests being included in the UI. - Check out the graphs in the main part of the control panel. Thats the distribution of
percent_correct
ness by each parameter. - There is a table below each graph. Try clicking on one of those links. For example, I'm going to click on datasetinputs.
- Notice anything different about the metadata stats at the top of this new page? The median
percent_correct
ness has jumped from 52% to 57%! - Recursively follow steps 6 -> 7 until
- You have a sample size that's too small to be meaningful.
- -- or -- You've reached a
percent_correctness
you are comfortable trading with.
NOTE -- The above TODO list is written for PredictionTest
s, but instructions apply for ClassifierTest
s also. (Just start at admin/c_charts
instead of admin/nn_charts
to tune ClassifierTests
. )
IFF you have a sample size that's too small to be meaningful, you'll want to modify the parameters in the predict_many_v2.py management command to narrow your search area to only those parameters. Re-run, and repeat the steps in "Finding a local maxima", above.
NOTE -- The above note is written for PredictionTest
s, but instructions apply for ClassifierTest
s also. (Just start at predict_many_sk.py
instead of predict_many_v2.py
to tune ClassifierTests
. )
IFF You've reached a percent_correctness
you are comfortable trading with, it's time to trade!
Open up trade.py and take a look at these lines. Do some of those parameters look familiar? They should, they are parameters you tuned in the predict_many_*
jobs above.
Replace the default variables in trade.py
with the parameters that you've found to be successful through your testing in the "Finding a local maxima" section.
Save your file, deploy it to your server, and run ./manage.py trade
. Congratulations, you are now trading with pytrader!
After you've been trading for a few hours, fire up admin/optimize
(or click the link in the admin). You'll see your trades over time and trade profitability over time.
- Check for any errors in your trades (first 2 graphs). If you see errors, you may want to check out
admin/history/trade/
(or follow the links in the django admin) to see why your trades are erroring out. Here is a common one:{u'error': u'Not enough BTC.'}
- There are some other graphs I've used to visually judge whether my trade.py parameters are correctly predicting the market. TBH, those are a little half baked at the moment, and could use a tune up. Github Issue.
Check out the admin/profit
page (or click the link in the admin).
- In the top two graphs, you'll see your balance vs deposited amount over time, and also a breakdown of your balances by currency.
- You'll also see your realized / unrealized gains in the bottom table.
- These graphs can be tuned by base currenty
At a high level, trade.py
- accepts predictor_configs
- trains NN/classifiers on those configs
- Runs a while loop that:
- determines if it's time to make a trade evaluation
- closes any existing open orders, if needed
- runs each predictor in self.predictor_configs, to preduct
recommendations
(an array of buy/sell/hold recommendations) - Determines whether to act_upon_recommendations.
- If a buy/sell action is determined to be attempted:
- Determine a price
- Determine a trade amount
- Perform the action and record the action
- Schedule an opposite trade, which will later be executed by ./manage.py scheduled_trades.
- Modify the
ticker_options
variable inpredict_many_sk.py
andpredict_many_v2.py
, and follow the instructions in "Finding a local maxima" above.
Granularity is the size of a chart candlestick. If
granularity == 1
, the trader will optimize on 1 minute candlesticks.trade.py
will trade every1
minutegranularity == 5
, the trader will optimize on 5 minute candlesticks.trade.py
will trade every5
minutesgranularity == 120
, the trader will optimize on 120 minute candlesticks.trade.py
will trade every120
minutes- etc
You could if you (shameless plug) write some code and submit a PR back to the repo. To test the code, I made a 1 BTC deposit on poloniex and traded with it. For me, 1 BTC is a negligible amount that was worth not having to manage the abstraction overhead of a simulation mode.
No.
len(self.predictor_configs)
over every self.granularity
minutes. see trade.py.
Just
- change
predict_many_*.py
to look at new configuration parameters. - -or- change
predictor_configs
in trade.py.
Can multiple instruments be traded at the same time? How do we tell pytrader which instruments to trade?
(assuming instrumetns == currency pairs)
Yes, change symbol
of the NN you'd like to trade with in predictor_configs
in trade.py.
Can pytrader take multiple positions in the same instrument in different directions? How is that managed?
Yes, it can. Here is an open issue for tracking the task of managing fees.
Right now trades will be closed after granularity
minutes.
This would be easy to tune and I would welcome a PR for this feature.
See this code. TLDR - The trade.py
script makes an attempt at determining it's confidence
in a position, and linearly adjusts its position from that. PRs welcome.
I noticed we're not running any NN's for USDT_BTC, but are for ETH_BTC. Is there a reason or is that just arbitrary?
Just arbitrary. My interest in trading USDT_BTC as a manual trader happened just as I was writing classifiertests.
This will depend upon your available computational resources and how quickly you want results from the NN/classifiers. As an example, on a small VM with 0.5G of memory, I went through the optimization above 3x, at a cost of ~12 hours of compute per day, before I started trading. Whether that was enough optimization or I was just lucky is a matter of debate at the moment.
The weighting is very rudimentary. See above.
Why do bad things happen when you try to tune the classifiers (e.g. adjust datasetinput based on simulations)?
This hasn't been implemented yet. You can alter parameters on the NNs, and should be able to adjust classifier type, but I haven't gotten around to adding more customization to classifiertests. We have an open issue here to track this.
./manage.py predict_many_v2
./manage.py predict_many_sk
./manage.py trade
These should ideally be scheduled via crontab:
./manage.py pull_deposits #checks API for any new deposits
./manage.py pull_balance #records your balance in USD, BTC, native coin.
./manage.py scheduled_trades # executes any _scheduled_ trades
./manage.py pull_prices #pulls price data from exchanges