Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect markup % reported on informational output #219

Open
dfelton opened this issue Jul 22, 2021 · 0 comments
Open

Incorrect markup % reported on informational output #219

dfelton opened this issue Jul 22, 2021 · 0 comments
Labels
bug Something isn't working Priority - Low

Comments

@dfelton
Copy link
Owner

dfelton commented Jul 22, 2021

Scenario:

  • Sell order is placed for a higher price than originally configured AND/OR Buy Order is placed for lower than originally configured
    • This is a common situation when the application is not running for an extended period of time, and market fluctuations move the price significantly above or below the trading range of a configured "position". Then application is turned back on while the market remains outside of the original price configurations, and application now buys for cheaper than it normally would have, or sells for higher than it normally would have on said "position".
  • Once sell order fills, and the Archiver logs the completion of the position, the informational output from the Archiver only takes into account the original configuration values, as opposed to what actually occurred.

Example output showing the problem:

2021-07-22 17:37:49	(7637)	SELL_PLACED	Order ID 48955464324	0.960241 SAND @ 0.50342 SAND/USD
2021-07-22 17:37:49		(original sell price: 0.40258)
2021-07-22 17:37:49	(7637)	SELL_FILLED	Order ID 48955464324	0.960241 SAND @ 0.50342 SAND/USD
2021-07-22 17:37:51	(7637)	ARCHIVED	BUY 1.007241 SAND @ 0.38249 SAND/USD --- SELL 0.960241 SAND @ 0.40258 SAND/USD (5.252% markup)
2021-07-22 17:37:51	Profit: 0.047 SAND
2021-07-22 17:37:51	Profit: 0.09727624999569 USD

On this line of output:

2021-07-22 17:37:51 (7637) ARCHIVED BUY 1.007241 SAND @ 0.38249 SAND/USD --- SELL 0.960241 SAND @ 0.40258 SAND/USD (5.252% markup)

We can see that it is still using 0.40258 as the price it believes the sell order was filled at. However the prior two lines clearly show otherwise:

2021-07-22 17:37:49	(7637)	SELL_PLACED	Order ID 48955464324	0.960241 SAND @ 0.50342 SAND/USD
2021-07-22 17:37:49		(original sell price: 0.40258)

Important Developer Notes

We need to be careful here when resolving this one. While it is OK to update the "informational only" output that gets sent to the terminal, we must NOT, under certain scenarios, unintentionally revise the amount logged to repeater_profit_bucket higher values in the base currency of the trade.

The reason for this is due to the way we handle funds on newly created positions configured for market prices above the current price. In this situation, it is common behavior to...... take funds necessary for these positions, immediately after creation of those newly created positions... this is a bit convoluted to explain and follow. Will aim to elaborate here using simple numbers to work with for the purpose of grasping this:

Hypothetical Scenario (for simplicity's sake, we'll ignore transaction fees):

  • User's account has $2,000 USD to work with. Assume no other repeater positions, or open orders of any kind, exist at all.
  • User executes ./bin/gemini repeater:bucket --add=2000 usd to move those funds into repeater_profit_bucket
    • This is so that come time to create positions, the application can enforce rules such as "is there even enough money in the account, to place the buy order(s) for positions, before those positions are even generated)
  • Current Market Price of BTC/USD is $1,000 USD per BTC
  • User uses configures a (new) repeater position under the BTC/USD pair.
    • This is done with the ./bin/gemini repeater:ppg command, accepting default option to pull funds from repeater_profit_bucket when generating position(s).
    • Configuration values for this (one any only) position:
      • Buy 1 BTC @ $2,000 USD per BTC
      • Sell 1 BTC @ $3,000 USD per BTC
  • Upon creation of this position, there is a very high chance of the initial buy order immediately filling (using the ForceMaker class, which is why we say "very high chance", but not guaranteed).
  • The Repeater has now acquired 1 BTC for half the price it will typically requires for this position.
  • Using the ./bin/gemini repeater:account command, user now sees on the USD Available Over Maker Deposit And Bucket(s) line of the report, that he/she has $1,000 sitting in the account, over what is necessary for actively maintain the live repeater order(s).
    • (again, this is because we've acquired the $2,000 BTC position for $1,000)
  • User decides to then move that $1,000 back into the bucket, and proceed to now generate more position(s) with those remaining funds
    • For the purpose of this scenario, lets assume it is for just ONE more repeater position configuration values:
      • Buy 2 BTC @ $500 USD per BTC
      • Sell 2 BTC @ $600 USD per BTC

At this point in the above scenario, we have two repeater positions, the buy order configurations for them are:

  • Buy 1 BTC @ $2,000 USD per BTC
  • Buy 2 BTC @ $500 USD per BTC

In total, to ensure these "continue to work", we need a minimum of $3,000 USD available, but we have only added $2,000 USD to the account.

Continuing this hypothetical scenario, lets say the market moves in a general upward direction, and before the "Buy 2 BTC @ $500 USD per BTC" position ever fills, what FIRST happens is the "Sell 1 BTC @ $3,000 USD per BTC" occurs first.

Technically the user has now made a $2,000 profit on this sale. And had he/she not performed that above step of moving "$1,000" back into the bucket after the (cheaper than configured) original buy order filled, we could log that $2,000 profit into repeater_profit_bucket. That full $2,000 profit could then be used to create more repeater positions.

However, in a sense, the user has already taken half of that profit and used it for the creation of more repeater positions already. If we were to log $2,000 profit into repeater_profit_bucket, the application would:

  • Immediately turn around and place a buy order for $2,000, reserving those funds for that buy order.
  • We now have only $1,000 available to work with, but a repeater_profit_bucket value of $2000 USD.

As currently programmed, the application would now:

  • Show a negative $1,000 value on the USD Available Over Maker Deposit And Bucket(s) line of the ./bin/gemini repeater:account report (which is strictly informational for humans, and not examined as any type of rule for any creation of repeater positions, or placement of orders)
  • Have $2,000 USD sitting in the repeater_profit_bucket
  • And (here's the problem of all this) allow for the user to execute the ./bin/gemini repeater:ppg command with option values that would result in the creation of trade_repeater positions totaling more money than we have available to us in our account
    • The effect of this, is the TradeRepeater\Buyer command would happily chug along and attempt to create these orders, until it has fully depleted all available funds, and eventually the exchange will reject a buy order attempt, causing the application to throw an InsufficientFundsException, and initiate an emergency shutdown of trading.
    • The user would now have to manually resolve this problem. One simple solution would be to add more funds, but if that isn't an option, it would require examining the repeater records, and deciding which ones to purge from the database.

TL;DR:

Fix the informational output. For now, unless we want to compose a solution to better handle the above problem, make sure the amount logged into repeater_profit_bucket remains the same as before.

@dfelton dfelton added bug Something isn't working Priority - Low labels Jul 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Priority - Low
Projects
None yet
Development

No branches or pull requests

1 participant