market-maker
market-maker copied to clipboard
Added capability of retrieving price info from Taptools
Most relevant new function is getTaptoolsPrice
defined in 'Prices.hs' .
ToDo: Add code to stop bot if price discrepancy is beyond some threshold.
Since Taptools aggregates the price provided by MinSwap (and provided by Maestro), it seems desirable to have the capability of fine-tunning the weights of each Prices Provider. Last commit enables that.
With last commit, buildPP
now checks that
- Length of list of weights coincides with number of prices providers;
- "Threshold2" is not smaller than "Threshold1".
Successfully tested:
- Working Taptools price feed.
- Config file is backwards compatible.
As well as these scenarios:
- Maestro price is unavailable (warns but MMBot continues)
- Taptools price is unavailable (warns but MMBot continues)
- Both Maestro and Taptools are unavailable (warns and closes all orders)
- Price mismatch lower than given threshold (continues normally; since price average changed, MMBot updates orders accordingly)
- Price mismatch larger than given threshold (closes all orders)
Note: as mechanism to flag changes while MMBot is running, the following files can be updated:
- offset_price.txt (initial content: 0)
- maestro_available.txt (initial content: True)
- taptools_available.txt (initial content: True)
State in exectueStrategy
(MakerBot.hs) is:
data MBFret = MBReady | MBSpooked1
{ mbsRelax1 ∷ !Int
, mbsWorse1 ∷ !Int
}
| MBSpooked2
{ mbsRelax2 ∷ !Int }
Counters' role are as follows:
-
mbsRelax1
: relaxation progress after prices providers return to agreement; new mismatch resets this counter. -
mbsWorse1
: if its max value is reached, state switches to "MBSpooked2". -
mbsRelax2
: same asmbsRelax1
but in the context of "outrageous" price mismatch.
As per convention in 'sample-preprod-maker-bot-config-gens-v2.yaml', flag files are:
- 'offset_price.txt': content of this file is artificially added to Maestro's price.
- 'maestro_available.txt': if its content is
False
, Maestro is artificially unavailable. - 'taptools_available.txt': it its content is
False
, Taptools is artificially unavailable.
If flag files are not present, default values (zero, True and True, respectively) are assumed.
To be on the safe side, I included secrets/
in .dockerignore. Was this necessary?
Latest changes:
- I removed all code duplication in testing suite.
- Added a third prices provider, so now
PricesProviderCfg
is:
data PricesProviderCfg =
MaestroPPC MaestroConfig
| TaptoolsPPC TaptoolsConfig
| MockPPC MockConfig
- The tested scenario is encoded in
testSequence :: [PPStatus]
- The validation logic is encoded in
testRequirements :: [[LogData -> Bool]]
Executing cabal test
resulted in:
OK (733.48s)
All 1 tests passed (733.51s)
Test suite pproviders-status-sequence: PASS
Test suite logged to:
/Users/antonio/code/haskell/geniusyield/market-maker/dist-newstyle/build/x86_64-osx/ghc-9.2.8/geniusyield-market-maker-0.3.0/t/pproviders-status-sequence/test/geniusyield-market-maker-0.3.0-pproviders-status-sequence.log
1 of 1 test suites (1 of 1 test cases) passed.
Latest commit addresses the following issues:
- If Maestro failed to provide price, execution would stop with an exception instead of relying on the other prices provider(s).
- The warning log message stating that a prices provider failed was not indicating which one.
- There was an inconsistency in where in the code the "prices provider fail" log message was being triggered.
With latest commit, prices provider failure consists of:
- Warning that "Some prices provider(s) failed: " and a list of those that failed.
- Logging the exceptions thrown by each failing prices provider.
Function logPricesProviderFail ∷ GYProviders → PriceIndicator → IO ()
, exported by module Strategies
, implements the above.
To elaborate, logging of a prices provider failure can occur if some, but not all, prices providers fail:
- While executing the trading strategy, or
- While on standby (in "spooked mode") waiting to confirm that all prices providers are again in agreement.
I believe this PR is ready to be merged into main
, and that the following outstanding issues can be worked out while MMBot is being tested on Preprod, as a separate PR.
Outstanding issues:
- [ ] Log each client's exception in the unlikely case that all prices providers fail. (Currently only a warning message announcing all prices providers failed is logged.)
- [x] Use CURL to query taptools prices (in order to be able to use https).
- [x] Consider removing parameter
pccAfterExitRelaxAim1
. - [x] Add security measure to make sure that secret taptools key is not logged in case of taptools failure.
- [ ] Improve testing suite by adding appropriate exceptions in the validation logic.
Experimentation shows that, with original definition of taptoolsManager
,
taptoolsManager :: Confidential Text -> IO Manager
taptoolsManager apiKey = newManager $ tlsManagerSettings { managerModifyRequest = withHeaders }
where
Confidential apiKey' = apiKey
withHeaders :: Request -> IO Request
withHeaders req = do
return $ req { requestHeaders = ("x-api-key", encodeUtf8 apiKey') :
filter (("x-api-key" /=) . fst) (requestHeaders req)
}
API key is automatically concealed in error logs.