Compare commits

...

16 Commits

Author SHA1 Message Date
robcaulk
2be3ff6bcb fix footer 2022-12-13 00:45:16 +01:00
robcaulk
457b8d8761 remove @ from github handles in acknowledgements 2022-12-11 20:24:53 +01:00
Robert Caulk
70dfa1435b
Add DOI to pandas citation 2022-12-07 16:42:25 +01:00
Emre
98fc5b6e65
Fix small typo 2022-11-26 21:07:27 +03:00
Emre
c126c26501
Fix typo 2022-11-26 20:59:48 +03:00
robcaulk
2159059b87 add longlong yu and add github handles 2022-11-26 10:25:56 +01:00
robcaulk
f0f4faca71 add ORCID for pascal schmidt 2022-11-26 00:55:24 +01:00
robcaulk
0bc647dbd9 add Emre Suzen (@aemr3) to acknowledgements 2022-11-26 00:53:02 +01:00
robcaulk
e3efb72efe add some changes recommended by @shagunsodhani 2022-10-31 17:51:06 +01:00
robcaulk
a9ef63cb20 add assets to joss sub-folder 2022-10-11 21:15:40 +02:00
robcaulk
3b0daff2a2 ensure compiled pdf is written to dir 2022-10-11 20:06:46 +02:00
robcaulk
67bd4f08e6 ensure paper compiles on push 2022-10-11 20:04:21 +02:00
robcaulk
4c2d291eaf add JOSS draft workflow 2022-10-11 20:01:17 +02:00
robcaulk
85df7faa98 add CNN prediction model 2022-10-11 19:55:28 +02:00
robcaulk
8d3ed03184 add JOSS paper sources 2022-10-11 19:46:25 +02:00
robcaulk
f5870a7540 add tensorflow interface 2022-09-26 21:55:23 +02:00
14 changed files with 1635 additions and 10 deletions

23
.github/workflows/draft-pdf.yml vendored Normal file
View File

@ -0,0 +1,23 @@
on: [push]
jobs:
paper:
runs-on: ubuntu-latest
name: Paper Draft
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Build draft PDF
uses: openjournals/openjournals-draft-action@master
with:
journal: joss
# This should be the path to the paper within your repo.
paper-path: docs/JOSS_paper/paper.md
- name: Upload
uses: actions/upload-artifact@v1
with:
name: paper
# This is the output path where Pandoc will write the compiled
# PDF. Note, this should be the same directory as the input
# paper.md
path: docs/JOSS_paper/paper.pdf

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 490 KiB

View File

@ -0,0 +1,15 @@
Dear Editors,
We present a paper for ``FreqAI`` a machine learning sandbox for researchers and citizen scientists alike.
There are a large number of authors, however all have contributed in a significant way to this paper.
For clarity the contribution of each author is outlined:
- Robert Caulk : Conception and software development
- Elin Tornquist : Theoretical brainstorming, data analysis, tool dev
- Matthias Voppichler : Software architecture and code review
- Andrew R. Lawless : Extensive testing, feature brainstorming
- Ryan McMullan : Extensive testing, feature brainstorming
- Wagner Costa Santos : Major backtesting developments, extensive testing
- Pascal Schmidt : Extensive testing, feature brainstorming
- Timothy C. Pogue : Webhooks forecast sharing
- Stefan P. Gehring : Extensive testing, feature brainstorming
- Johan van der Vlugt : Extensive testing, feature brainstorming

207
docs/JOSS_paper/paper.bib Normal file
View File

@ -0,0 +1,207 @@
@article{scikit-learn,
title={Scikit-learn: Machine Learning in {P}ython},
author={Pedregosa, F. and Varoquaux, G. and Gramfort, A. and Michel, V.
and Thirion, B. and Grisel, O. and Blondel, M. and Prettenhofer, P.
and Weiss, R. and Dubourg, V. and Vanderplas, J. and Passos, A. and
Cournapeau, D. and Brucher, M. and Perrot, M. and Duchesnay, E.},
journal={Journal of Machine Learning Research},
volume={12},
pages={2825--2830},
year={2011}
}
@inproceedings{catboost,
author = {Prokhorenkova, Liudmila and Gusev, Gleb and Vorobev, Aleksandr and Dorogush, Anna Veronika and Gulin, Andrey},
title = {CatBoost: Unbiased Boosting with Categorical Features},
year = {2018},
publisher = {Curran Associates Inc.},
address = {Red Hook, NY, USA},
abstract = {This paper presents the key algorithmic techniques behind CatBoost, a new gradient boosting toolkit. Their combination leads to CatBoost outperforming other publicly available boosting implementations in terms of quality on a variety of datasets. Two critical algorithmic advances introduced in CatBoost are the implementation of ordered boosting, a permutation-driven alternative to the classic algorithm, and an innovative algorithm for processing categorical features. Both techniques were created to fight a prediction shift caused by a special kind of target leakage present in all currently existing implementations of gradient boosting algorithms. In this paper, we provide a detailed analysis of this problem and demonstrate that proposed algorithms solve it effectively, leading to excellent empirical results.},
booktitle = {Proceedings of the 32nd International Conference on Neural Information Processing Systems},
pages = {66396649},
numpages = {11},
location = {Montr\'{e}al, Canada},
series = {NIPS'18}
}
@article{lightgbm,
title={Lightgbm: A highly efficient gradient boosting decision tree},
author={Ke, Guolin and Meng, Qi and Finley, Thomas and Wang, Taifeng and Chen, Wei and Ma, Weidong and Ye, Qiwei and Liu, Tie-Yan},
journal={Advances in neural information processing systems},
volume={30},
pages={3146--3154},
year={2017}
}
@inproceedings{xgboost,
author = {Chen, Tianqi and Guestrin, Carlos},
title = {{XGBoost}: A Scalable Tree Boosting System},
booktitle = {Proceedings of the 22nd ACM SIGKDD International Conference on Knowledge Discovery and Data Mining},
series = {KDD '16},
year = {2016},
isbn = {978-1-4503-4232-2},
location = {San Francisco, California, USA},
pages = {785--794},
numpages = {10},
url = {http://doi.acm.org/10.1145/2939672.2939785},
doi = {10.1145/2939672.2939785},
acmid = {2939785},
publisher = {ACM},
address = {New York, NY, USA},
keywords = {large-scale machine learning},
}
@article{stable-baselines3,
author = {Antonin Raffin and Ashley Hill and Adam Gleave and Anssi Kanervisto and Maximilian Ernestus and Noah Dormann},
title = {Stable-Baselines3: Reliable Reinforcement Learning Implementations},
journal = {Journal of Machine Learning Research},
year = {2021},
volume = {22},
number = {268},
pages = {1-8},
url = {http://jmlr.org/papers/v22/20-1364.html}
}
@misc{openai,
title={OpenAI Gym},
author={Greg Brockman and Vicki Cheung and Ludwig Pettersson and Jonas Schneider and John Schulman and Jie Tang and Wojciech Zaremba},
year={2016},
eprint={1606.01540},
archivePrefix={arXiv},
primaryClass={cs.LG}
}
@misc{tensorflow,
title={ {TensorFlow}: Large-Scale Machine Learning on Heterogeneous Systems},
url={https://www.tensorflow.org/},
note={Software available from tensorflow.org},
author={
Mart\'{i}n~Abadi and
Ashish~Agarwal and
Paul~Barham and
Eugene~Brevdo and
Zhifeng~Chen and
Craig~Citro and
Greg~S.~Corrado and
Andy~Davis and
Jeffrey~Dean and
Matthieu~Devin and
Sanjay~Ghemawat and
Ian~Goodfellow and
Andrew~Harp and
Geoffrey~Irving and
Michael~Isard and
Yangqing Jia and
Rafal~Jozefowicz and
Lukasz~Kaiser and
Manjunath~Kudlur and
Josh~Levenberg and
Dandelion~Man\'{e} and
Rajat~Monga and
Sherry~Moore and
Derek~Murray and
Chris~Olah and
Mike~Schuster and
Jonathon~Shlens and
Benoit~Steiner and
Ilya~Sutskever and
Kunal~Talwar and
Paul~Tucker and
Vincent~Vanhoucke and
Vijay~Vasudevan and
Fernanda~Vi\'{e}gas and
Oriol~Vinyals and
Pete~Warden and
Martin~Wattenberg and
Martin~Wicke and
Yuan~Yu and
Xiaoqiang~Zheng},
year={2015},
}
@incollection{pytorch,
title = {PyTorch: An Imperative Style, High-Performance Deep Learning Library},
author = {Paszke, Adam and Gross, Sam and Massa, Francisco and Lerer, Adam and Bradbury, James and Chanan, Gregory and Killeen, Trevor and Lin, Zeming and Gimelshein, Natalia and Antiga, Luca and Desmaison, Alban and Kopf, Andreas and Yang, Edward and DeVito, Zachary and Raison, Martin and Tejani, Alykhan and Chilamkurthy, Sasank and Steiner, Benoit and Fang, Lu and Bai, Junjie and Chintala, Soumith},
booktitle = {Advances in Neural Information Processing Systems 32},
editor = {H. Wallach and H. Larochelle and A. Beygelzimer and F. d\textquotesingle Alch\'{e}-Buc and E. Fox and R. Garnett},
pages = {8024--8035},
year = {2019},
publisher = {Curran Associates, Inc.},
url = {http://papers.neurips.cc/paper/9015-pytorch-an-imperative-style-high-performance-deep-learning-library.pdf}
}
@ARTICLE{scipy,
author = {Virtanen, Pauli and Gommers, Ralf and Oliphant, Travis E. and
Haberland, Matt and Reddy, Tyler and Cournapeau, David and
Burovski, Evgeni and Peterson, Pearu and Weckesser, Warren and
Bright, Jonathan and {van der Walt}, St{\'e}fan J. and
Brett, Matthew and Wilson, Joshua and Millman, K. Jarrod and
Mayorov, Nikolay and Nelson, Andrew R. J. and Jones, Eric and
Kern, Robert and Larson, Eric and Carey, C J and
Polat, {\.I}lhan and Feng, Yu and Moore, Eric W. and
{VanderPlas}, Jake and Laxalde, Denis and Perktold, Josef and
Cimrman, Robert and Henriksen, Ian and Quintero, E. A. and
Harris, Charles R. and Archibald, Anne M. and
Ribeiro, Ant{\^o}nio H. and Pedregosa, Fabian and
{van Mulbregt}, Paul and {SciPy 1.0 Contributors}},
title = {{{SciPy} 1.0: Fundamental Algorithms for Scientific
Computing in Python}},
journal = {Nature Methods},
year = {2020},
volume = {17},
pages = {261--272},
adsurl = {https://rdcu.be/b08Wh},
doi = {10.1038/s41592-019-0686-2},
}
@Article{numpy,
title = {Array programming with {NumPy}},
author = {Charles R. Harris and K. Jarrod Millman and St{\'{e}}fan J.
van der Walt and Ralf Gommers and Pauli Virtanen and David
Cournapeau and Eric Wieser and Julian Taylor and Sebastian
Berg and Nathaniel J. Smith and Robert Kern and Matti Picus
and Stephan Hoyer and Marten H. van Kerkwijk and Matthew
Brett and Allan Haldane and Jaime Fern{\'{a}}ndez del
R{\'{i}}o and Mark Wiebe and Pearu Peterson and Pierre
G{\'{e}}rard-Marchant and Kevin Sheppard and Tyler Reddy and
Warren Weckesser and Hameer Abbasi and Christoph Gohlke and
Travis E. Oliphant},
year = {2020},
month = sep,
journal = {Nature},
volume = {585},
number = {7825},
pages = {357--362},
doi = {10.1038/s41586-020-2649-2},
publisher = {Springer Science and Business Media {LLC}},
url = {https://doi.org/10.1038/s41586-020-2649-2}
}
@inproceedings{pandas,
title={Data structures for statistical computing in python},
author={McKinney, Wes and others},
booktitle={Proceedings of the 9th Python in Science Conference},
volume={445},
pages={51--56},
year={2010},
organization={Austin, TX},
doi={10.25080/Majora-92bf1922-00a}
}
@online{finrl,
title = {AI4Finance-Foundation},
year = 2022,
url = {https://github.com/AI4Finance-Foundation/FinRL},
urldate = {2022-09-30}
}
@online{tensortrade,
title = {tensortrade},
year = 2022,
url = {https://tensortradex.readthedocs.io/en/latest/L},
urldate = {2022-09-30}
}

941
docs/JOSS_paper/paper.jats Normal file
View File

@ -0,0 +1,941 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Publishing DTD v1.2 20190208//EN"
"JATS-publishing1.dtd">
<article xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:xlink="http://www.w3.org/1999/xlink" dtd-version="1.2" article-type="other">
<front>
<journal-meta>
<journal-id></journal-id>
<journal-title-group>
<journal-title>Journal of Open Source Software</journal-title>
<abbrev-journal-title>JOSS</abbrev-journal-title>
</journal-title-group>
<issn publication-format="electronic">2475-9066</issn>
<publisher>
<publisher-name>Open Journals</publisher-name>
</publisher>
</journal-meta>
<article-meta>
<article-id pub-id-type="publisher-id">0</article-id>
<article-id pub-id-type="doi">N/A</article-id>
<title-group>
<article-title><monospace>FreqAI</monospace>: generalizing adaptive
modeling for chaotic time-series market forecasts</article-title>
</title-group>
<contrib-group>
<contrib contrib-type="author">
<contrib-id contrib-id-type="orcid">0000-0001-5618-8629</contrib-id>
<name>
<surname>Ph.D</surname>
<given-names>Robert A. Caulk</given-names>
</name>
<xref ref-type="aff" rid="aff-1"/>
<xref ref-type="aff" rid="aff-2"/>
</contrib>
<contrib contrib-type="author">
<contrib-id contrib-id-type="orcid">0000-0003-3289-8604</contrib-id>
<name>
<surname>Ph.D</surname>
<given-names>Elin Törnquist</given-names>
</name>
<xref ref-type="aff" rid="aff-1"/>
<xref ref-type="aff" rid="aff-2"/>
</contrib>
<contrib contrib-type="author">
<name>
<surname>Voppichler</surname>
<given-names>Matthias</given-names>
</name>
<xref ref-type="aff" rid="aff-2"/>
</contrib>
<contrib contrib-type="author">
<name>
<surname>Lawless</surname>
<given-names>Andrew R.</given-names>
</name>
<xref ref-type="aff" rid="aff-2"/>
</contrib>
<contrib contrib-type="author">
<name>
<surname>McMullan</surname>
<given-names>Ryan</given-names>
</name>
<xref ref-type="aff" rid="aff-2"/>
</contrib>
<contrib contrib-type="author">
<name>
<surname>Santos</surname>
<given-names>Wagner Costa</given-names>
</name>
<xref ref-type="aff" rid="aff-1"/>
<xref ref-type="aff" rid="aff-2"/>
</contrib>
<contrib contrib-type="author">
<name>
<surname>Pogue</surname>
<given-names>Timothy C.</given-names>
</name>
<xref ref-type="aff" rid="aff-1"/>
<xref ref-type="aff" rid="aff-2"/>
</contrib>
<contrib contrib-type="author">
<name>
<surname>van der Vlugt</surname>
<given-names>Johan</given-names>
</name>
<xref ref-type="aff" rid="aff-2"/>
</contrib>
<contrib contrib-type="author">
<name>
<surname>Gehring</surname>
<given-names>Stefan P.</given-names>
</name>
<xref ref-type="aff" rid="aff-2"/>
</contrib>
<contrib contrib-type="author">
<name>
<surname>Schmidt</surname>
<given-names>Pascal</given-names>
</name>
<xref ref-type="aff" rid="aff-2"/>
</contrib>
<aff id="aff-1">
<institution-wrap>
<institution>Emergent Methods LLC, Arvada Colorado, 80005,
USA</institution>
</institution-wrap>
</aff>
<aff id="aff-2">
<institution-wrap>
<institution>Freqtrade open source project</institution>
</institution-wrap>
</aff>
</contrib-group>
<volume>¿VOL?</volume>
<issue>¿ISSUE?</issue>
<fpage>¿PAGE?</fpage>
<permissions>
<copyright-statement>Authors of papers retain copyright and release the
work under a Creative Commons Attribution 4.0 International License (CC
BY 4.0)</copyright-statement>
<copyright-year>2022</copyright-year>
<copyright-holder>The article authors</copyright-holder>
<license license-type="open-access" xlink:href="https://creativecommons.org/licenses/by/4.0/">
<license-p>Authors of papers retain copyright and release the work under
a Creative Commons Attribution 4.0 International License (CC BY
4.0)</license-p>
</license>
</permissions>
<kwd-group kwd-group-type="author">
<kwd>Python</kwd>
<kwd>Machine Learning</kwd>
<kwd>adaptive modeling</kwd>
<kwd>chaotic systems</kwd>
<kwd>time-series forecasting</kwd>
</kwd-group>
</article-meta>
</front>
<body>
<sec id="statement-of-need">
<title>Statement of need</title>
<p>Forecasting chaotic time-series based systems, such as
equity/cryptocurrency markets, requires a broad set of tools geared
toward testing a wide range of hypotheses. Fortunately, a recent
maturation of robust machine learning libraries
(e.g. <monospace>scikit-learn</monospace>), has opened up a wide range
of research possibilities. Scientists from a diverse range of fields
can now easily prototype their studies on an abundance of established
machine learning algorithms. Similarly, these user-friendly libraries
enable “citzen scientists” to use their basic Python skills for
data-exploration. However, leveraging these machine learning libraries
on historical and live chaotic data sources can be logistically
difficult and expensive. Additionally, robust data-collection,
storage, and handling presents a disparate challenge.
<ext-link ext-link-type="uri" xlink:href="https://www.freqtrade.io/en/latest/freqai/"><monospace>FreqAI</monospace></ext-link>
aims to provide a generalized and extensible open-sourced framework
geared toward live deployments of adaptive modeling for market
forecasting. The <monospace>FreqAI</monospace> framework is
effectively a sandbox for the rich world of open-source machine
learning libraries. Inside the <monospace>FreqAI</monospace> sandbox,
users find they can combine a wide variety of third-party libraries to
test creative hypotheses on a free live 24/7 chaotic data source -
cryptocurrency exchange data.</p>
</sec>
<sec id="summary">
<title>Summary</title>
<p><ext-link ext-link-type="uri" xlink:href="https://www.freqtrade.io/en/latest/freqai/"><monospace>FreqAI</monospace></ext-link>
evolved from a desire to test and compare a range of adaptive
time-series forecasting methods on chaotic data. Cryptocurrency
markets provide a unique data source since they are operational 24/7
and the data is freely available. Luckily, an existing open-source
software,
<ext-link ext-link-type="uri" xlink:href="https://www.freqtrade.io/en/stable/"><monospace>Freqtrade</monospace></ext-link>,
had already matured under a range of talented developers to support
robust data collection/storage, as well as robust live environmental
interactions for standard algorithmic trading.
<monospace>Freqtrade</monospace> also provides a set of data
analysis/visualization tools for the evaluation of historical
performance as well as live environmental feedback.
<monospace>FreqAI</monospace> builds on top of
<monospace>Freqtrade</monospace> to include a user-friendly well
tested interface for integrating external machine learning libraries
for adaptive time-series forecasting. Beyond enabling the integration
of existing libraries, <monospace>FreqAI</monospace> hosts a range of
custom algorithms and methodologies aimed at improving computational
and predictive performances. Thus, <monospace>FreqAI</monospace>
contains a range of unique features which can be easily tested in
combination with all the existing Python-accessible machine learning
libraries to generate novel research on live and historical data.</p>
<p>The high-level overview of the software is depicted in Figure
1.</p>
<p><named-content content-type="image">freqai-algo</named-content>
<italic>Abstracted overview of FreqAI algorithm</italic></p>
<sec id="connecting-machine-learning-libraries">
<title>Connecting machine learning libraries</title>
<p>Although the <monospace>FreqAI</monospace> framework is designed
to accommodate any Python library in the “Model training” and
“Feature set engineering” portions of the software (Figure 1), it
already boasts a wide range of well documented examples based on
various combinations of:</p>
<list list-type="bullet">
<list-item>
<p>scikit-learn
(<xref alt="Pedregosa et al., 2011" rid="ref-scikit-learn" ref-type="bibr">Pedregosa
et al., 2011</xref>), Catboost
(<xref alt="Prokhorenkova et al., 2018" rid="ref-catboost" ref-type="bibr">Prokhorenkova
et al., 2018</xref>), LightGBM
(<xref alt="Ke et al., 2017" rid="ref-lightgbm" ref-type="bibr">Ke
et al., 2017</xref>), XGBoost
(<xref alt="Chen &amp; Guestrin, 2016" rid="ref-xgboost" ref-type="bibr">Chen
&amp; Guestrin, 2016</xref>), stable_baselines3
(<xref alt="Raffin et al., 2021" rid="ref-stable-baselines3" ref-type="bibr">Raffin
et al., 2021</xref>), openai gym
(<xref alt="Brockman et al., 2016" rid="ref-openai" ref-type="bibr">Brockman
et al., 2016</xref>), tensorflow
(<xref alt="Abadi et al., 2015" rid="ref-tensorflow" ref-type="bibr">Abadi
et al., 2015</xref>), pytorch
(<xref alt="Paszke et al., 2019" rid="ref-pytorch" ref-type="bibr">Paszke
et al., 2019</xref>), Scipy
(<xref alt="Virtanen et al., 2020" rid="ref-scipy" ref-type="bibr">Virtanen
et al., 2020</xref>), Numpy
(<xref alt="Harris et al., 2020" rid="ref-numpy" ref-type="bibr">Harris
et al., 2020</xref>), and pandas
(<xref alt="McKinney &amp; others, 2010" rid="ref-pandas" ref-type="bibr">McKinney
&amp; others, 2010</xref>).</p>
</list-item>
</list>
<p>These mature projects contain a wide range of peer-reviewed and
industry standard methods, including:</p>
<list list-type="bullet">
<list-item>
<p>Regression, Classification, Neural Networks, Reinforcement
Learning, Support Vector Machines, Principal Component Analysis,
point clustering, and much more.</p>
</list-item>
</list>
<p>which are all leveraged in <monospace>FreqAI</monospace> for
users to use as templates or extend with their own methods.</p>
</sec>
<sec id="furnishing-novel-methods-and-features">
<title>Furnishing novel methods and features</title>
<p>Beyond the industry standard methods available through external
libraries - <monospace>FreqAI</monospace> includes novel methods
which are not available anywhere else in the open-source (or
scientific) world. For example, <monospace>FreqAI</monospace>
provides :</p>
<list list-type="bullet">
<list-item>
<p>a custom algorithm/methodology for adaptive modeling</p>
</list-item>
<list-item>
<p>rapid and self-monitored feature engineering tools</p>
</list-item>
<list-item>
<p>unique model features/indicators</p>
</list-item>
<list-item>
<p>optimized data collection algorithms</p>
</list-item>
<list-item>
<p>safely integrated outlier detection methods</p>
</list-item>
<list-item>
<p>websocket communicated forecasts</p>
</list-item>
</list>
<p>Of particular interest for researchers,
<monospace>FreqAI</monospace> provides the option of large scale
experimentation via an optimized websocket communications
interface.</p>
</sec>
<sec id="optimizing-the-back-end">
<title>Optimizing the back-end</title>
<p><monospace>FreqAI</monospace> aims to make it simple for users to
combine all the above tools to run studies based in two distinct
modules:</p>
<list list-type="bullet">
<list-item>
<p>backtesting studies</p>
</list-item>
<list-item>
<p>live-deployments</p>
</list-item>
</list>
<p>Both of these modules and their respective data management
systems are built on top of
<ext-link ext-link-type="uri" xlink:href="https://www.freqtrade.io/en/latest/"><monospace>Freqtrade</monospace></ext-link>,
a mature and actively developed cryptocurrency trading software.
This means that <monospace>FreqAI</monospace> benefits from a wide
range of tangential/disparate feature developments such as:</p>
<list list-type="bullet">
<list-item>
<p>FreqUI, a graphical interface for backtesting and live
monitoring</p>
</list-item>
<list-item>
<p>telegram control</p>
</list-item>
<list-item>
<p>robust database handling</p>
</list-item>
<list-item>
<p>futures/leverage trading</p>
</list-item>
<list-item>
<p>dollar cost averaging</p>
</list-item>
<list-item>
<p>trading strategy handling</p>
</list-item>
<list-item>
<p>a variety of free data sources via CCXT (FTX, Binance, Kucoin
etc.)</p>
</list-item>
</list>
<p>These features derive from a strong external developer community
that shares in the benefit and stability of a communal CI
(Continuous Integration) system. Beyond the developer community,
<monospace>FreqAI</monospace> benefits strongly from the userbase of
<monospace>Freqtrade</monospace>, where most
<monospace>FreqAI</monospace> beta-testers/developers originated.
This symbiotic relationship between <monospace>Freqtrade</monospace>
and <monospace>FreqAI</monospace> ignited a thoroughly tested
<ext-link ext-link-type="uri" xlink:href="https://github.com/freqtrade/freqtrade/pull/6832"><monospace>beta</monospace></ext-link>,
which demanded a four month beta and
<ext-link ext-link-type="uri" xlink:href="https://www.freqtrade.io/en/latest/freqai/">comprehensive
documentation</ext-link> containing:</p>
<list list-type="bullet">
<list-item>
<p>numerous example scripts</p>
</list-item>
<list-item>
<p>a full parameter table</p>
</list-item>
<list-item>
<p>methodological descriptions</p>
</list-item>
<list-item>
<p>high-resolution diagrams/figures</p>
</list-item>
<list-item>
<p>detailed parameter setting recommendations</p>
</list-item>
</list>
</sec>
<sec id="providing-a-reproducible-foundation-for-researchers">
<title>Providing a reproducible foundation for researchers</title>
<p><monospace>FreqAI</monospace> provides an extensible, robust,
framework for researchers and citizen data scientists. The
<monospace>FreqAI</monospace> sandbox enables rapid conception and
testing of exotic hypotheses. From a research perspective,
<monospace>FreqAI</monospace> handles the multitude of logistics
associated with live deployments, historical backtesting, and
feature engineering. With <monospace>FreqAI</monospace>, researchers
can focus on their primary interests of feature engineering and
hypothesis testing rather than figuring out how to collect and
handle data. Further - the well maintained and easily installed
open-source framework of <monospace>FreqAI</monospace> enables
reproducible scientific studies. This reproducibility component is
essential to general scientific advancement in time-series
forecasting for chaotic systems.</p>
</sec>
</sec>
<sec id="technical-details">
<title>Technical details</title>
<p>Typical users configure <monospace>FreqAI</monospace> via two
files:</p>
<list list-type="order">
<list-item>
<p>A <monospace>configuration</monospace> file
(<monospace>--config</monospace>) which provides access to the
full parameter list available
<ext-link ext-link-type="uri" xlink:href="https://www.freqtrade.io/en/latest/freqai/">here</ext-link>:</p>
</list-item>
</list>
<list list-type="bullet">
<list-item>
<p>control high-level feature engineering</p>
</list-item>
<list-item>
<p>customize adaptive modeling techniques</p>
</list-item>
<list-item>
<p>set any model training parameters available in third-party
libraries</p>
</list-item>
<list-item>
<p>manage adaptive modeling parameters (retrain frequency,
training window size, continual learning, etc.)</p>
</list-item>
</list>
<list list-type="order">
<list-item>
<label>2.</label>
<p>A strategy file (<monospace>--strategy</monospace>) where
users:</p>
</list-item>
</list>
<list list-type="bullet">
<list-item>
<p>list of the base training features</p>
</list-item>
<list-item>
<p>set standard technical-analysis strategies</p>
</list-item>
<list-item>
<p>control trade entry/exit criteria</p>
</list-item>
</list>
<p>With these two files, most users can exploit a wide range of
pre-existing integrations in <monospace>Catboost</monospace> and 7
other libraries with a simple command:</p>
<preformat>freqtrade trade --config config_freqai.example.json --strategy FreqaiExampleStrategy --freqaimodel CatboostRegressor</preformat>
<p>Advanced users will edit one of the existing
<monospace>--freqaimodel</monospace> files, which are simply an
children of the <monospace>IFreqaiModel</monospace> (details below).
Within these files, advanced users can customize training procedures,
prediction procedures, outlier detection methods, data preparation,
data saving methods, etc. This is all configured in a way where they
can customize as little or as much as they want. This flexible
customization is owed to the foundational architecture in
<monospace>FreqAI</monospace>, which is comprised of three distinct
Python objects:</p>
<list list-type="bullet">
<list-item>
<p><monospace>IFreqaiModel</monospace></p>
<list list-type="bullet">
<list-item>
<p>A singular long-lived object containing all the necessary
logic to collect data, store data, process data, engineer
features, run training, and inference models.</p>
</list-item>
</list>
</list-item>
<list-item>
<p><monospace>FreqaiDataKitchen</monospace></p>
<list list-type="bullet">
<list-item>
<p>A short-lived object which is uniquely created for each
asset/model. Beyond metadata, it also contains a variety of
data processing tools.</p>
</list-item>
</list>
</list-item>
<list-item>
<p><monospace>FreqaiDataDrawer</monospace></p>
<list list-type="bullet">
<list-item>
<p>Singular long-lived object containing all the historical
predictions, models, and save/load methods.</p>
</list-item>
</list>
</list-item>
</list>
<p>These objects interact with one another with one goal in mind - to
provide a clean data set to machine learning experts/enthusiasts at
the user endpoint. These power-users interact with an inherited
<monospace>IFreqaiModel</monospace> that allows them to dig as deep or
as shallow as they wish into the inheritence tree. Typical power-users
focus their efforts on customizing training procedures and testing
exotic functionalities available in third-party libraries. Thus,
power-users are freed from the algorithmic weight associated with data
management, and can instead focus their energy on testing creative
hypotheses. Meanwhile, some users choose to override deeper
functionalities within <monospace>IFreqaiModel</monospace> to help
them craft unique data structures and training procedures.</p>
<p>The class structure and algorithmic details are depicted in the
following diagram:</p>
<p><named-content content-type="image">image</named-content>
<italic>Class diagram summarizing object interactions in
FreqAI</italic></p>
</sec>
<sec id="online-documentation">
<title>Online documentation</title>
<p>The documentation for
<ext-link ext-link-type="uri" xlink:href="https://www.freqtrade.io/en/latest/freqai/"><monospace>FreqAI</monospace></ext-link>
is available online at
<ext-link ext-link-type="uri" xlink:href="https://www.freqtrade.io/en/latest/freqai/">https://www.freqtrade.io/en/latest/freqai/</ext-link>
and covers a wide range of materials:</p>
<list list-type="bullet">
<list-item>
<p>Quick-start with a single command and example files -
(beginners)</p>
</list-item>
<list-item>
<p>Introduction to the feature engineering interface and basic
configurations - (intermediate users)</p>
</list-item>
<list-item>
<p>Parameter table with indepth descriptions and default parameter
setting recommendations - (intermediate users)</p>
</list-item>
<list-item>
<p>Data analysis and post-processing - (advanced users)</p>
</list-item>
<list-item>
<p>Methodological considerations complemented by high resolution
figures - (advanced users)</p>
</list-item>
<list-item>
<p>Instructions for integrating third party machine learning
libraries into custom prediction models - (advanced users)</p>
</list-item>
<list-item>
<p>Software architectural description with class diagram -
(developers)</p>
</list-item>
<list-item>
<p>File structure descriptions - (developers)</p>
</list-item>
</list>
<p>The docs direct users to a variety of pre-made examples which
integrate <monospace>Catboost</monospace>,
<monospace>LightGBM</monospace>, <monospace>XGBoost</monospace>,
<monospace>Sklearn</monospace>,
<monospace>stable_baselines3</monospace>,
<monospace>torch</monospace>, <monospace>tensorflow</monospace>.
Meanwhile, developers will also find thorough docstrings and type
hinting throughout the source code to aid in code readability and
customization.</p>
<p><monospace>FreqAI</monospace> also benefits from a strong support
network of users and developers on the
<ext-link ext-link-type="uri" xlink:href="https://discord.gg/w6nDM6cM4y"><monospace>Freqtrade</monospace>
discord</ext-link> as well as on the
<ext-link ext-link-type="uri" xlink:href="https://discord.gg/xE4RMg4QYw"><monospace>FreqAI</monospace>
discord</ext-link>. Within the <monospace>FreqAI</monospace> discord,
users will find a deep and easily searched knowledge base containing
common errors. But more importantly, users in the
<monospace>FreqAI</monospace> discord share anectdotal and
quantitative observations which compare performance between various
third-party libraries and methods.</p>
</sec>
<sec id="state-of-the-field">
<title>State of the field</title>
<p>There are two other open-source tools which are geared toward
helping users build models for time-series forecasts on market based
data. However, each of these tools suffer from a non-generalized
frameworks that do not permit comparison of methods and libraries.
Additionally, they do not permit easy live-deployments or
adaptive-modeling methods. For example, two open-sourced projects
called
<ext-link ext-link-type="uri" xlink:href="https://tensortradex.readthedocs.io/en/latest/"><monospace>tensortrade</monospace></ext-link>
(<xref alt="Tensortrade, 2022" rid="ref-tensortrade" ref-type="bibr"><italic>Tensortrade</italic>,
2022</xref>) and
<ext-link ext-link-type="uri" xlink:href="https://github.com/AI4Finance-Foundation/FinRL"><monospace>FinRL</monospace></ext-link>
(<xref alt="AI4Finance-Foundation, 2022" rid="ref-finrl" ref-type="bibr"><italic>AI4Finance-Foundation</italic>,
2022</xref>) limit users to the exploration of reinforcement learning
on historical data. These softwares also do not provide robust live
deployments, they do not furnish novel feature engineering algorithms,
and they do not provide custom data analysis tools.
<monospace>FreqAI</monospace> fills the gap.</p>
</sec>
<sec id="on-going-research">
<title>On-going research</title>
<p>Emergent Methods, based in Arvada CO, is actively using
<monospace>FreqAI</monospace> to perform large scale experiments aimed
at comparing machine learning libraries in live and historical
environments. Past projects include backtesting parametric sweeps,
while active projects include a 3 week live deployment comparison
between <monospace>CatboosRegressor</monospace>,
<monospace>LightGBMRegressor</monospace>, and
<monospace>XGBoostRegressor</monospace>. Results from these studies
are on track for publication in scientific journals as well as more
general data science blogs (e.g. Medium).</p>
</sec>
<sec id="installing-and-running-freqai">
<title>Installing and running <monospace>FreqAI</monospace></title>
<p><monospace>FreqAI</monospace> is automatically installed with
<monospace>Freqtrade</monospace> using the following commands on linux
systems:</p>
<preformat>git clone git@github.com:freqtrade/freqtrade.git
cd freqtrade
./setup.sh -i</preformat>
<p>However, <monospace>FreqAI</monospace> also benefits from
<monospace>Freqtrade</monospace> docker distributions, and can be run
with docker by pulling the stable or develop images from
<monospace>Freqtrade</monospace> distributions.</p>
</sec>
<sec id="funding-sources">
<title>Funding sources</title>
<p><ext-link ext-link-type="uri" xlink:href="https://www.freqtrade.io/en/latest/freqai/"><monospace>FreqAI</monospace></ext-link>
has had no official sponsors, and is entirely grass roots. All
donations into the project (e.g. the GitHub sponsor system) are kept
inside the project to help support development of open-sourced and
communally beneficial features.</p>
</sec>
<sec id="acknowledgements">
<title>Acknowledgements</title>
<p>We would like to acknowledge various beta testers of
<monospace>FreqAI</monospace>:</p>
<list list-type="bullet">
<list-item>
<p>Richárd Józsa</p>
</list-item>
<list-item>
<p>Juha Nykänen</p>
</list-item>
<list-item>
<p>Salah Lamkadem</p>
</list-item>
</list>
<p>As well as various <monospace>Freqtrade</monospace>
<ext-link ext-link-type="uri" xlink:href="https://github.com/freqtrade/freqtrade/graphs/contributors">developers</ext-link>
maintaining tangential, yet essential, modules.</p>
</sec>
</body>
<back>
<ref-list>
<ref id="ref-scikit-learn">
<element-citation publication-type="article-journal">
<person-group person-group-type="author">
<name><surname>Pedregosa</surname><given-names>F.</given-names></name>
<name><surname>Varoquaux</surname><given-names>G.</given-names></name>
<name><surname>Gramfort</surname><given-names>A.</given-names></name>
<name><surname>Michel</surname><given-names>V.</given-names></name>
<name><surname>Thirion</surname><given-names>B.</given-names></name>
<name><surname>Grisel</surname><given-names>O.</given-names></name>
<name><surname>Blondel</surname><given-names>M.</given-names></name>
<name><surname>Prettenhofer</surname><given-names>P.</given-names></name>
<name><surname>Weiss</surname><given-names>R.</given-names></name>
<name><surname>Dubourg</surname><given-names>V.</given-names></name>
<name><surname>Vanderplas</surname><given-names>J.</given-names></name>
<name><surname>Passos</surname><given-names>A.</given-names></name>
<name><surname>Cournapeau</surname><given-names>D.</given-names></name>
<name><surname>Brucher</surname><given-names>M.</given-names></name>
<name><surname>Perrot</surname><given-names>M.</given-names></name>
<name><surname>Duchesnay</surname><given-names>E.</given-names></name>
</person-group>
<article-title>Scikit-learn: Machine learning in Python</article-title>
<source>Journal of Machine Learning Research</source>
<year iso-8601-date="2011">2011</year>
<volume>12</volume>
<fpage>2825</fpage>
<lpage>2830</lpage>
</element-citation>
</ref>
<ref id="ref-catboost">
<element-citation publication-type="paper-conference">
<person-group person-group-type="author">
<name><surname>Prokhorenkova</surname><given-names>Liudmila</given-names></name>
<name><surname>Gusev</surname><given-names>Gleb</given-names></name>
<name><surname>Vorobev</surname><given-names>Aleksandr</given-names></name>
<name><surname>Dorogush</surname><given-names>Anna Veronika</given-names></name>
<name><surname>Gulin</surname><given-names>Andrey</given-names></name>
</person-group>
<article-title>CatBoost: Unbiased boosting with categorical features</article-title>
<source>Proceedings of the 32nd international conference on neural information processing systems</source>
<publisher-name>Curran Associates Inc.</publisher-name>
<publisher-loc>Red Hook, NY, USA</publisher-loc>
<year iso-8601-date="2018">2018</year>
<fpage>6639</fpage>
<lpage>6649</lpage>
</element-citation>
</ref>
<ref id="ref-lightgbm">
<element-citation publication-type="article-journal">
<person-group person-group-type="author">
<name><surname>Ke</surname><given-names>Guolin</given-names></name>
<name><surname>Meng</surname><given-names>Qi</given-names></name>
<name><surname>Finley</surname><given-names>Thomas</given-names></name>
<name><surname>Wang</surname><given-names>Taifeng</given-names></name>
<name><surname>Chen</surname><given-names>Wei</given-names></name>
<name><surname>Ma</surname><given-names>Weidong</given-names></name>
<name><surname>Ye</surname><given-names>Qiwei</given-names></name>
<name><surname>Liu</surname><given-names>Tie-Yan</given-names></name>
</person-group>
<article-title>Lightgbm: A highly efficient gradient boosting decision tree</article-title>
<source>Advances in neural information processing systems</source>
<year iso-8601-date="2017">2017</year>
<volume>30</volume>
<fpage>3146</fpage>
<lpage>3154</lpage>
</element-citation>
</ref>
<ref id="ref-xgboost">
<element-citation publication-type="paper-conference">
<person-group person-group-type="author">
<name><surname>Chen</surname><given-names>Tianqi</given-names></name>
<name><surname>Guestrin</surname><given-names>Carlos</given-names></name>
</person-group>
<article-title>XGBoost: A scalable tree boosting system</article-title>
<source>Proceedings of the 22nd ACM SIGKDD international conference on knowledge discovery and data mining</source>
<publisher-name>ACM</publisher-name>
<publisher-loc>New York, NY, USA</publisher-loc>
<year iso-8601-date="2016">2016</year>
<isbn>978-1-4503-4232-2</isbn>
<uri>http://doi.acm.org/10.1145/2939672.2939785</uri>
<pub-id pub-id-type="doi">10.1145/2939672.2939785</pub-id>
<fpage>785</fpage>
<lpage>794</lpage>
</element-citation>
</ref>
<ref id="ref-stable-baselines3">
<element-citation publication-type="article-journal">
<person-group person-group-type="author">
<name><surname>Raffin</surname><given-names>Antonin</given-names></name>
<name><surname>Hill</surname><given-names>Ashley</given-names></name>
<name><surname>Gleave</surname><given-names>Adam</given-names></name>
<name><surname>Kanervisto</surname><given-names>Anssi</given-names></name>
<name><surname>Ernestus</surname><given-names>Maximilian</given-names></name>
<name><surname>Dormann</surname><given-names>Noah</given-names></name>
</person-group>
<article-title>Stable-Baselines3: Reliable reinforcement learning implementations</article-title>
<source>Journal of Machine Learning Research</source>
<year iso-8601-date="2021">2021</year>
<volume>22</volume>
<issue>268</issue>
<uri>http://jmlr.org/papers/v22/20-1364.html</uri>
<fpage>1</fpage>
<lpage>8</lpage>
</element-citation>
</ref>
<ref id="ref-openai">
<element-citation>
<person-group person-group-type="author">
<name><surname>Brockman</surname><given-names>Greg</given-names></name>
<name><surname>Cheung</surname><given-names>Vicki</given-names></name>
<name><surname>Pettersson</surname><given-names>Ludwig</given-names></name>
<name><surname>Schneider</surname><given-names>Jonas</given-names></name>
<name><surname>Schulman</surname><given-names>John</given-names></name>
<name><surname>Tang</surname><given-names>Jie</given-names></name>
<name><surname>Zaremba</surname><given-names>Wojciech</given-names></name>
</person-group>
<article-title>OpenAI gym</article-title>
<year iso-8601-date="2016">2016</year>
<uri>https://arxiv.org/abs/1606.01540</uri>
</element-citation>
</ref>
<ref id="ref-tensorflow">
<element-citation>
<person-group person-group-type="author">
<name><surname>Abadi</surname><given-names>Martín</given-names></name>
<name><surname>Agarwal</surname><given-names>Ashish</given-names></name>
<name><surname>Barham</surname><given-names>Paul</given-names></name>
<name><surname>Brevdo</surname><given-names>Eugene</given-names></name>
<name><surname>Chen</surname><given-names>Zhifeng</given-names></name>
<name><surname>Citro</surname><given-names>Craig</given-names></name>
<name><surname>Corrado</surname><given-names>Greg S.</given-names></name>
<name><surname>Davis</surname><given-names>Andy</given-names></name>
<name><surname>Dean</surname><given-names>Jeffrey</given-names></name>
<name><surname>Devin</surname><given-names>Matthieu</given-names></name>
<name><surname>Ghemawat</surname><given-names>Sanjay</given-names></name>
<name><surname>Goodfellow</surname><given-names>Ian</given-names></name>
<name><surname>Harp</surname><given-names>Andrew</given-names></name>
<name><surname>Irving</surname><given-names>Geoffrey</given-names></name>
<name><surname>Isard</surname><given-names>Michael</given-names></name>
<name><surname>Jia</surname><given-names>Yangqing</given-names></name>
<name><surname>Jozefowicz</surname><given-names>Rafal</given-names></name>
<name><surname>Kaiser</surname><given-names>Lukasz</given-names></name>
<name><surname>Kudlur</surname><given-names>Manjunath</given-names></name>
<name><surname>Levenberg</surname><given-names>Josh</given-names></name>
<name><surname>Mané</surname><given-names>Dandelion</given-names></name>
<name><surname>Monga</surname><given-names>Rajat</given-names></name>
<name><surname>Moore</surname><given-names>Sherry</given-names></name>
<name><surname>Murray</surname><given-names>Derek</given-names></name>
<name><surname>Olah</surname><given-names>Chris</given-names></name>
<name><surname>Schuster</surname><given-names>Mike</given-names></name>
<name><surname>Shlens</surname><given-names>Jonathon</given-names></name>
<name><surname>Steiner</surname><given-names>Benoit</given-names></name>
<name><surname>Sutskever</surname><given-names>Ilya</given-names></name>
<name><surname>Talwar</surname><given-names>Kunal</given-names></name>
<name><surname>Tucker</surname><given-names>Paul</given-names></name>
<name><surname>Vanhoucke</surname><given-names>Vincent</given-names></name>
<name><surname>Vasudevan</surname><given-names>Vijay</given-names></name>
<name><surname>Viégas</surname><given-names>Fernanda</given-names></name>
<name><surname>Vinyals</surname><given-names>Oriol</given-names></name>
<name><surname>Warden</surname><given-names>Pete</given-names></name>
<name><surname>Wattenberg</surname><given-names>Martin</given-names></name>
<name><surname>Wicke</surname><given-names>Martin</given-names></name>
<name><surname>Yu</surname><given-names>Yuan</given-names></name>
<name><surname>Zheng</surname><given-names>Xiaoqiang</given-names></name>
</person-group>
<article-title>TensorFlow: Large-scale machine learning on heterogeneous systems</article-title>
<year iso-8601-date="2015">2015</year>
<uri>https://www.tensorflow.org/</uri>
</element-citation>
</ref>
<ref id="ref-pytorch">
<element-citation publication-type="chapter">
<person-group person-group-type="author">
<name><surname>Paszke</surname><given-names>Adam</given-names></name>
<name><surname>Gross</surname><given-names>Sam</given-names></name>
<name><surname>Massa</surname><given-names>Francisco</given-names></name>
<name><surname>Lerer</surname><given-names>Adam</given-names></name>
<name><surname>Bradbury</surname><given-names>James</given-names></name>
<name><surname>Chanan</surname><given-names>Gregory</given-names></name>
<name><surname>Killeen</surname><given-names>Trevor</given-names></name>
<name><surname>Lin</surname><given-names>Zeming</given-names></name>
<name><surname>Gimelshein</surname><given-names>Natalia</given-names></name>
<name><surname>Antiga</surname><given-names>Luca</given-names></name>
<name><surname>Desmaison</surname><given-names>Alban</given-names></name>
<name><surname>Kopf</surname><given-names>Andreas</given-names></name>
<name><surname>Yang</surname><given-names>Edward</given-names></name>
<name><surname>DeVito</surname><given-names>Zachary</given-names></name>
<name><surname>Raison</surname><given-names>Martin</given-names></name>
<name><surname>Tejani</surname><given-names>Alykhan</given-names></name>
<name><surname>Chilamkurthy</surname><given-names>Sasank</given-names></name>
<name><surname>Steiner</surname><given-names>Benoit</given-names></name>
<name><surname>Fang</surname><given-names>Lu</given-names></name>
<name><surname>Bai</surname><given-names>Junjie</given-names></name>
<name><surname>Chintala</surname><given-names>Soumith</given-names></name>
</person-group>
<article-title>PyTorch: An imperative style, high-performance deep learning library</article-title>
<source>Advances in neural information processing systems 32</source>
<person-group person-group-type="editor">
<name><surname>Wallach</surname><given-names>H.</given-names></name>
<name><surname>Larochelle</surname><given-names>H.</given-names></name>
<name><surname>Beygelzimer</surname><given-names>A.</given-names></name>
<name><surname>dAlché-Buc</surname><given-names>F.</given-names></name>
<name><surname>Fox</surname><given-names>E.</given-names></name>
<name><surname>Garnett</surname><given-names>R.</given-names></name>
</person-group>
<publisher-name>Curran Associates, Inc.</publisher-name>
<year iso-8601-date="2019">2019</year>
<uri>http://papers.neurips.cc/paper/9015-pytorch-an-imperative-style-high-performance-deep-learning-library.pdf</uri>
<fpage>8024</fpage>
<lpage>8035</lpage>
</element-citation>
</ref>
<ref id="ref-scipy">
<element-citation publication-type="article-journal">
<person-group person-group-type="author">
<name><surname>Virtanen</surname><given-names>Pauli</given-names></name>
<name><surname>Gommers</surname><given-names>Ralf</given-names></name>
<name><surname>Oliphant</surname><given-names>Travis E.</given-names></name>
<name><surname>Haberland</surname><given-names>Matt</given-names></name>
<name><surname>Reddy</surname><given-names>Tyler</given-names></name>
<name><surname>Cournapeau</surname><given-names>David</given-names></name>
<name><surname>Burovski</surname><given-names>Evgeni</given-names></name>
<name><surname>Peterson</surname><given-names>Pearu</given-names></name>
<name><surname>Weckesser</surname><given-names>Warren</given-names></name>
<name><surname>Bright</surname><given-names>Jonathan</given-names></name>
<name><surname>van der Walt</surname><given-names>Stéfan J.</given-names></name>
<name><surname>Brett</surname><given-names>Matthew</given-names></name>
<name><surname>Wilson</surname><given-names>Joshua</given-names></name>
<name><surname>Millman</surname><given-names>K. Jarrod</given-names></name>
<name><surname>Mayorov</surname><given-names>Nikolay</given-names></name>
<name><surname>Nelson</surname><given-names>Andrew R. J.</given-names></name>
<name><surname>Jones</surname><given-names>Eric</given-names></name>
<name><surname>Kern</surname><given-names>Robert</given-names></name>
<name><surname>Larson</surname><given-names>Eric</given-names></name>
<name><surname>Carey</surname><given-names>C J</given-names></name>
<name><surname>Polat</surname><given-names>İlhan</given-names></name>
<name><surname>Feng</surname><given-names>Yu</given-names></name>
<name><surname>Moore</surname><given-names>Eric W.</given-names></name>
<name><surname>VanderPlas</surname><given-names>Jake</given-names></name>
<name><surname>Laxalde</surname><given-names>Denis</given-names></name>
<name><surname>Perktold</surname><given-names>Josef</given-names></name>
<name><surname>Cimrman</surname><given-names>Robert</given-names></name>
<name><surname>Henriksen</surname><given-names>Ian</given-names></name>
<name><surname>Quintero</surname><given-names>E. A.</given-names></name>
<name><surname>Harris</surname><given-names>Charles R.</given-names></name>
<name><surname>Archibald</surname><given-names>Anne M.</given-names></name>
<name><surname>Ribeiro</surname><given-names>Antônio H.</given-names></name>
<name><surname>Pedregosa</surname><given-names>Fabian</given-names></name>
<name><surname>van Mulbregt</surname><given-names>Paul</given-names></name>
<string-name>SciPy 1.0 Contributors</string-name>
</person-group>
<article-title>SciPy 1.0: Fundamental Algorithms for Scientific Computing in Python</article-title>
<source>Nature Methods</source>
<year iso-8601-date="2020">2020</year>
<volume>17</volume>
<pub-id pub-id-type="doi">10.1038/s41592-019-0686-2</pub-id>
<fpage>261</fpage>
<lpage>272</lpage>
</element-citation>
</ref>
<ref id="ref-numpy">
<element-citation publication-type="article-journal">
<person-group person-group-type="author">
<name><surname>Harris</surname><given-names>Charles R.</given-names></name>
<name><surname>Millman</surname><given-names>K. Jarrod</given-names></name>
<name><surname>Walt</surname><given-names>Stéfan J. van der</given-names></name>
<name><surname>Gommers</surname><given-names>Ralf</given-names></name>
<name><surname>Virtanen</surname><given-names>Pauli</given-names></name>
<name><surname>Cournapeau</surname><given-names>David</given-names></name>
<name><surname>Wieser</surname><given-names>Eric</given-names></name>
<name><surname>Taylor</surname><given-names>Julian</given-names></name>
<name><surname>Berg</surname><given-names>Sebastian</given-names></name>
<name><surname>Smith</surname><given-names>Nathaniel J.</given-names></name>
<name><surname>Kern</surname><given-names>Robert</given-names></name>
<name><surname>Picus</surname><given-names>Matti</given-names></name>
<name><surname>Hoyer</surname><given-names>Stephan</given-names></name>
<name><surname>Kerkwijk</surname><given-names>Marten H. van</given-names></name>
<name><surname>Brett</surname><given-names>Matthew</given-names></name>
<name><surname>Haldane</surname><given-names>Allan</given-names></name>
<name><surname>Río</surname><given-names>Jaime Fernández del</given-names></name>
<name><surname>Wiebe</surname><given-names>Mark</given-names></name>
<name><surname>Peterson</surname><given-names>Pearu</given-names></name>
<name><surname>Gérard-Marchant</surname><given-names>Pierre</given-names></name>
<name><surname>Sheppard</surname><given-names>Kevin</given-names></name>
<name><surname>Reddy</surname><given-names>Tyler</given-names></name>
<name><surname>Weckesser</surname><given-names>Warren</given-names></name>
<name><surname>Abbasi</surname><given-names>Hameer</given-names></name>
<name><surname>Gohlke</surname><given-names>Christoph</given-names></name>
<name><surname>Oliphant</surname><given-names>Travis E.</given-names></name>
</person-group>
<article-title>Array programming with NumPy</article-title>
<source>Nature</source>
<publisher-name>Springer Science; Business Media LLC</publisher-name>
<year iso-8601-date="2020-09">2020</year><month>09</month>
<volume>585</volume>
<issue>7825</issue>
<uri>https://doi.org/10.1038/s41586-020-2649-2</uri>
<pub-id pub-id-type="doi">10.1038/s41586-020-2649-2</pub-id>
<fpage>357</fpage>
<lpage>362</lpage>
</element-citation>
</ref>
<ref id="ref-pandas">
<element-citation publication-type="paper-conference">
<person-group person-group-type="author">
<name><surname>McKinney</surname><given-names>Wes</given-names></name>
<name><surname>others</surname></name>
</person-group>
<article-title>Data structures for statistical computing in python</article-title>
<source>Proceedings of the 9th python in science conference</source>
<publisher-name>Austin, TX</publisher-name>
<year iso-8601-date="2010">2010</year>
<volume>445</volume>
<fpage>51</fpage>
<lpage>56</lpage>
</element-citation>
</ref>
<ref id="ref-finrl">
<element-citation publication-type="webpage">
<article-title>AI4Finance-foundation</article-title>
<year iso-8601-date="2022">2022</year>
<date-in-citation content-type="access-date"><year iso-8601-date="2022-09-30">2022</year><month>09</month><day>30</day></date-in-citation>
<uri>https://github.com/AI4Finance-Foundation/FinRL</uri>
</element-citation>
</ref>
<ref id="ref-tensortrade">
<element-citation publication-type="webpage">
<article-title>Tensortrade</article-title>
<year iso-8601-date="2022">2022</year>
<date-in-citation content-type="access-date"><year iso-8601-date="2022-09-30">2022</year><month>09</month><day>30</day></date-in-citation>
<uri>https://tensortradex.readthedocs.io/en/latest/L</uri>
</element-citation>
</ref>
</ref-list>
</back>
</article>

212
docs/JOSS_paper/paper.md Normal file
View File

@ -0,0 +1,212 @@
---
title: '`FreqAI`: generalizing adaptive modeling for chaotic time-series market forecasts'
tags:
- Python
- Machine Learning
- adaptive modeling
- chaotic systems
- time-series forecasting
authors:
- name: Robert A. Caulk
orcid: 0000-0001-5618-8629
affiliation: 1, 2
- name: Elin Törnquist
orcid: 0000-0003-3289-8604
affiliation: 1, 2
- name: Matthias Voppichler
orcid:
affiliation: 2
- name: Andrew R. Lawless
orcid:
affiliation: 2
- name: Ryan McMullan
orcid:
affiliation: 2
- name: Wagner Costa Santos
orcid:
affiliation: 1, 2
- name: Timothy C. Pogue
orcid:
affiliation: 1, 2
- name: Johan van der Vlugt
orcid:
affiliation: 2
- name: Stefan P. Gehring
orcid:
affiliation: 2
- name: Pascal Schmidt
orcid: 0000-0001-9328-4345
affiliation: 2
<!-- affiliation: "1, 2" # (Multiple affiliations must be quoted) -->
affiliations:
- name: Emergent Methods LLC, Arvada Colorado, 80005, USA
index: 1
- name: Freqtrade open source project
index: 2
date: October 2022
bibliography: paper.bib
---
# Statement of need
Forecasting chaotic time-series based systems, such as equity/cryptocurrency markets, requires a broad set of tools geared toward testing a wide range of hypotheses. Fortunately, a recent maturation of robust machine learning libraries (e.g. `scikit-learn`), has opened up a wide range of research possibilities. Scientists from a diverse range of fields can now easily prototype their studies on an abundance of established machine learning algorithms. Similarly, these user-friendly libraries enable "citizen scientists" to use their basic Python skills for data-exploration. However, leveraging these machine learning libraries on historical and live chaotic data sources can be logistically difficult and expensive. Additionally, robust data-collection, storage, and handling presents a disparate challenge. [`FreqAI`](https://www.freqtrade.io/en/latest/freqai/) aims to provide a generalized and extensible open-sourced framework geared toward live deployments of adaptive modeling for market forecasting. The `FreqAI` framework is effectively a sandbox for the rich world of open-source machine learning libraries. Inside the `FreqAI` sandbox, users find they can combine a wide variety of third-party libraries to test creative hypotheses on a free live 24/7 chaotic data source - cryptocurrency exchange data.
# Summary
[`FreqAI`](https://www.freqtrade.io/en/latest/freqai/) evolved from a desire to test and compare a range of adaptive time-series forecasting methods on chaotic data. Cryptocurrency markets provide a unique data source since they are operational 24/7 and the data is freely available via a variety of open-sourced [exchange APIs](https://docs.ccxt.com/en/latest/manual.html#exchange-structure). Luckily, an existing open-source software, [`Freqtrade`](https://www.freqtrade.io/en/stable/), had already matured under a range of talented developers to support robust data collection/storage, as well as robust live environmental interactions for standard algorithmic trading. `Freqtrade` also provides a set of data analysis/visualization tools for the evaluation of historical performance as well as live environmental feedback. `FreqAI` builds on top of `Freqtrade` to include a user-friendly well tested interface for integrating external machine learning libraries for adaptive time-series forecasting. Beyond enabling the integration of existing libraries, `FreqAI` hosts a range of custom algorithms and methodologies aimed at improving computational and predictive performances. Thus, `FreqAI` contains a range of unique features which can be easily tested in combination with all the existing Python-accessible machine learning libraries to generate novel research on live and historical data.
The high-level overview of the software is depicted in Figure 1.
![freqai-algo](assets/freqai_algo.jpg)
*Abstracted overview of FreqAI algorithm*
## Connecting machine learning libraries
Although the `FreqAI` framework is designed to accommodate any Python library in the "Model training" and "Feature set engineering" portions of the software (Figure 1), it already boasts a wide range of well documented examples based on various combinations of:
* scikit-learn [@scikit-learn], Catboost [@catboost], LightGBM [@lightgbm], XGBoost [@xgboost], stable_baselines3 [@stable-baselines3], openai gym [@openai], tensorflow [@tensorflow], pytorch [@pytorch], Scipy [@scipy], Numpy [@numpy], and pandas [@pandas].
These mature projects contain a wide range of peer-reviewed and industry standard methods, including:
* Regression, Classification, Neural Networks, Reinforcement Learning, Support Vector Machines, Principal Component Analysis, point clustering, and much more.
which are all leveraged in `FreqAI` for users to use as templates or extend with their own methods.
## Furnishing novel methods and features
Beyond the industry standard methods available through external libraries - `FreqAI` includes novel methods which are not available anywhere else in the open-source (or scientific) world. For example, `FreqAI` provides :
* a custom algorithm/methodology for adaptive modeling details [here](https://www.freqtrade.io/en/stable/freqai/#general-approach) and [here](https://www.freqtrade.io/en/stable/freqai-developers/#project-architecture)
* rapid and self-monitored feature engineering tools, details [here](https://www.freqtrade.io/en/stable/freqai-feature-engineering/#feature-engineering)
* unique model features/indicators, such as the [inlier metric](https://www.freqtrade.io/en/stable/freqai-feature-engineering/#inlier-metric)
* optimized data collection/storage algorithms, all code shown [here](https://github.com/freqtrade/freqtrade/blob/develop/freqtrade/freqai/data_drawer.py)
* safely integrated outlier detection methods, details [here](https://www.freqtrade.io/en/stable/freqai-feature-engineering/#outlier-detection)
* websocket communicated forecasts, details [here](https://www.freqtrade.io/en/stable/producer-consumer/)
Of particular interest for researchers, `FreqAI` provides the option of large scale experimentation via an optimized [websocket communications interface](https://www.freqtrade.io/en/stable/producer-consumer/).
## Optimizing the back-end
`FreqAI` aims to make it simple for users to combine all the above tools to run studies based in two distinct modules:
* backtesting studies
* live-deployments
Both of these modules and their respective data management systems are built on top of [`Freqtrade`](https://www.freqtrade.io/en/latest/), a mature and actively developed cryptocurrency trading software. This means that `FreqAI` benefits from a wide range of tangential/disparate feature developments such as:
* FreqUI, a graphical interface for backtesting and live monitoring
* telegram control
* robust database handling
* futures/leverage trading
* dollar cost averaging
* trading strategy handling
* a variety of free data sources via [CCXT](https://docs.ccxt.com/en/latest/manual.html#exchange-structure) (FTX, Binance, Kucoin etc.)
These features derive from a strong external developer community that shares in the benefit and stability of a communal CI (Continuous Integration) system. Beyond the developer community, `FreqAI` benefits strongly from the userbase of `Freqtrade`, where most `FreqAI` beta-testers/developers originated. This symbiotic relationship between `Freqtrade` and `FreqAI` ignited a thoroughly tested [`beta`](https://github.com/freqtrade/freqtrade/pull/6832), which demanded a four month beta and [comprehensive documentation](https://www.freqtrade.io/en/latest/freqai/) containing:
* numerous example scripts
* a full parameter table
* methodological descriptions
* high-resolution diagrams/figures
* detailed parameter setting recommendations
## Providing a reproducible foundation for researchers
`FreqAI` provides an extensible, robust, framework for researchers and citizen data scientists. The `FreqAI` sandbox enables rapid conception and testing of exotic hypotheses. From a research perspective, `FreqAI` handles the multitude of logistics associated with live deployments, historical backtesting, and feature engineering. With `FreqAI`, researchers can focus on their primary interests of feature engineering and hypothesis testing rather than figuring out how to collect and handle data. Further - the well maintained and easily installed open-source framework of `FreqAI` enables reproducible scientific studies. This reproducibility component is essential to general scientific advancement in time-series forecasting for chaotic systems.
# Technical details
Typical users configure `FreqAI` via two files:
1. A `configuration` file (`--config`) which provides access to the full parameter list available [here](https://www.freqtrade.io/en/latest/freqai/):
* control high-level feature engineering
* customize adaptive modeling techniques
* set any model training parameters available in third-party libraries
* manage adaptive modeling parameters (retrain frequency, training window size, continual learning, etc.)
2. A strategy file (`--strategy`) where users:
* list of the base training features
* set standard technical-analysis strategies
* control trade entry/exit criteria
With these two files, most users can exploit a wide range of pre-existing integrations in `Catboost` and 7 other libraries with a simple command:
```
freqtrade trade --config config_freqai.example.json --strategy FreqaiExampleStrategy --freqaimodel CatboostRegressor
```
Advanced users will edit one of the existing `--freqaimodel` files, which are simply an children of the `IFreqaiModel` (details below). Within these files, advanced users can customize training procedures, prediction procedures, outlier detection methods, data preparation, data saving methods, etc. This is all configured in a way where they can customize as little or as much as they want. This flexible customization is owed to the foundational architecture in `FreqAI`, which is comprised of three distinct Python objects:
* `IFreqaiModel`
* A singular long-lived object containing all the necessary logic to collect data, store data, process data, engineer features, run training, and inference models.
* `FreqaiDataKitchen`
* A short-lived object which is uniquely created for each asset/model. Beyond metadata, it also contains a variety of data processing tools.
* `FreqaiDataDrawer`
* Singular long-lived object containing all the historical predictions, models, and save/load methods.
These objects interact with one another with one goal in mind - to provide a clean data set to machine learning experts/enthusiasts at the user endpoint. These power-users interact with an inherited `IFreqaiModel` that allows them to dig as deep or as shallow as they wish into the inheritence tree. Typical power-users focus their efforts on customizing training procedures and testing exotic functionalities available in third-party libraries. Thus, power-users are freed from the algorithmic weight associated with data management, and can instead focus their energy on testing creative hypotheses. Meanwhile, some users choose to override deeper functionalities within `IFreqaiModel` to help them craft unique data structures and training procedures.
The class structure and algorithmic details are depicted in the following diagram:
![image](assets/freqai_algorithm-diagram.jpg)
*Class diagram summarizing object interactions in FreqAI*
# Online documentation
The documentation for [`FreqAI`](https://www.freqtrade.io/en/latest/freqai/) is available online at [https://www.freqtrade.io/en/latest/freqai/](https://www.freqtrade.io/en/latest/freqai/) and covers a wide range of materials:
* Quick-start with a single command and example files - (beginners)
* Introduction to the feature engineering interface and basic configurations - (intermediate users)
* Parameter table with indepth descriptions and default parameter setting recommendations - (intermediate users)
* Data analysis and post-processing - (advanced users)
* Methodological considerations complemented by high resolution figures - (advanced users)
* Instructions for integrating third party machine learning libraries into custom prediction models - (advanced users)
* Software architectural description with class diagram - (developers)
* File structure descriptions - (developers)
The docs direct users to a variety of pre-made examples which integrate `Catboost`, `LightGBM`, `XGBoost`, `Sklearn`, `stable_baselines3`, `torch`, `tensorflow`. Meanwhile, developers will also find thorough docstrings and type hinting throughout the source code to aid in code readability and customization.
`FreqAI` also benefits from a strong support network of users and developers on the [`Freqtrade` discord](https://discord.gg/w6nDM6cM4y) as well as on the [`FreqAI` discord](https://discord.gg/xE4RMg4QYw). Within the `FreqAI` discord, users will find a deep and easily searched knowledge base containing common errors. But more importantly, users in the `FreqAI` discord share anectdotal and quantitative observations which compare performance between various third-party libraries and methods.
# State of the field
There are two other open-source tools which are geared toward helping users build models for time-series forecasts on market based data. However, each of these tools suffer from a non-generalized frameworks that do not permit comparison of methods and libraries. Additionally, they do not permit easy live-deployments or adaptive-modeling methods. For example, two open-sourced projects called [`tensortrade`](https://tensortradex.readthedocs.io/en/latest/) [@tensortrade] and [`FinRL`](https://github.com/AI4Finance-Foundation/FinRL) [@finrl] limit users to the exploration of reinforcement learning on historical data. These softwares also do not provide robust live deployments, they do not furnish novel feature engineering algorithms, and they do not provide custom data analysis tools. `FreqAI` fills the gap.
# On-going research
Emergent Methods, based in Arvada CO, is actively using `FreqAI` to perform large scale experiments aimed at comparing machine learning libraries in live and historical environments. Past projects include backtesting parametric sweeps, while active projects include a 3 week live deployment comparison between `CatboostRegressor`, `LightGBMRegressor`, and `XGBoostRegressor`. Results from these studies are planned for submission to scientific journals as well as more general data science blogs (e.g. Medium).
# Installing and running `FreqAI`
`FreqAI` is automatically installed with `Freqtrade` using the following commands on linux systems:
```
git clone git@github.com:freqtrade/freqtrade.git
cd freqtrade
./setup.sh -i
```
However, `FreqAI` also benefits from `Freqtrade` docker distributions, and can be run with docker by pulling the stable or develop images from `Freqtrade` distributions.
# Funding sources
[`FreqAI`](https://www.freqtrade.io/en/latest/freqai/) has had no official sponsors, and is entirely grass roots. All donations into the project (e.g. the GitHub sponsor system) are kept inside the project to help support development of open-sourced and communally beneficial features.
# Acknowledgements
We would like to acknowledge various beta testers of `FreqAI`:
- Longlong Yu (lolongcovas)
- Richárd Józsa (richardjozsa)
- Juha Nykänen (suikula)
- Emre Suzen (aemr3)
- Salah Lamkadem (ikonx)
As well as various `Freqtrade` [developers](https://github.com/freqtrade/freqtrade/graphs/contributors) maintaining tangential, yet essential, modules.
# References

BIN
docs/JOSS_paper/paper.pdf Normal file

Binary file not shown.

View File

@ -58,4 +58,4 @@ Mandatory parameters are marked as **Required** and have to be set in one of the
| `model_reward_parameters` | Parameters used inside the user customizable `calculate_reward()` function in `ReinforcementLearner.py` <br> **Datatype:** int. | `model_reward_parameters` | Parameters used inside the user customizable `calculate_reward()` function in `ReinforcementLearner.py` <br> **Datatype:** int.
| | **Extraneous parameters** | | **Extraneous parameters**
| `keras` | If the selected model makes use of Keras (typical for Tensorflow-based prediction models), this flag needs to be activated so that the model save/loading follows Keras standards. <br> **Datatype:** Boolean. <br> Default: `False`. | `keras` | If the selected model makes use of Keras (typical for Tensorflow-based prediction models), this flag needs to be activated so that the model save/loading follows Keras standards. <br> **Datatype:** Boolean. <br> Default: `False`.
| `conv_width` | The width of a convolutional neural network input tensor. This replaces the need for shifting candles (`include_shifted_candles`) by feeding in historical data points as the second dimension of the tensor. Technically, this parameter can also be used for regressors, but it only adds computational overhead and does not change the model training/prediction. <br> **Datatype:** Integer. <br> Default: `2`. | `conv_width` | The width of a convolutional neural network input tensor. This replaces the need for shifting candles (`include_shifted_candles`) by feeding in historical data points as the second dimension of the tensor. Technically, this parameter can also be used for regressors, but it only adds computational overhead and does not change the model training/prediction. <br> **Datatype:** Integer. <br> Default: `2`.

View File

@ -3,10 +3,10 @@ from time import time
from typing import Any from typing import Any
from pandas import DataFrame from pandas import DataFrame
import numpy as np
from freqtrade.freqai.data_kitchen import FreqaiDataKitchen from freqtrade.freqai.data_kitchen import FreqaiDataKitchen
from freqtrade.freqai.freqai_interface import IFreqaiModel from freqtrade.freqai.freqai_interface import IFreqaiModel
import tensorflow as tf
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -17,6 +17,13 @@ class BaseTensorFlowModel(IFreqaiModel):
User *must* inherit from this class and set fit() and predict(). User *must* inherit from this class and set fit() and predict().
""" """
def __init__(self, **kwargs):
super().__init__(config=kwargs['config'])
self.keras = True
if self.ft_params.get("DI_threshold", 0):
self.ft_params["DI_threshold"] = 0
logger.warning("DI threshold is not configured for Keras models yet. Deactivating.")
def train( def train(
self, unfiltered_df: DataFrame, pair: str, dk: FreqaiDataKitchen, **kwargs self, unfiltered_df: DataFrame, pair: str, dk: FreqaiDataKitchen, **kwargs
) -> Any: ) -> Any:
@ -68,3 +75,76 @@ class BaseTensorFlowModel(IFreqaiModel):
f"({end_time - start_time:.2f} secs) --------------------") f"({end_time - start_time:.2f} secs) --------------------")
return model return model
class WindowGenerator:
def __init__(
self,
input_width,
label_width,
shift,
train_df=None,
val_df=None,
test_df=None,
train_labels=None,
val_labels=None,
test_labels=None,
batch_size=None,
):
# Store the raw data.
self.train_df = train_df
self.val_df = val_df
self.test_df = test_df
self.train_labels = train_labels
self.val_labels = val_labels
self.test_labels = test_labels
self.batch_size = batch_size
self.input_width = input_width
self.label_width = label_width
self.shift = shift
self.total_window_size = input_width + shift
self.input_slice = slice(0, input_width)
self.input_indices = np.arange(self.total_window_size)[self.input_slice]
def make_dataset(self, data, labels=None):
data = np.array(data, dtype=np.float32)
if labels is not None:
labels = np.array(labels, dtype=np.float32)
ds = tf.keras.preprocessing.timeseries_dataset_from_array(
data=data,
targets=labels,
sequence_length=self.total_window_size,
sequence_stride=1,
sampling_rate=1,
shuffle=False,
batch_size=self.batch_size,
)
return ds
@property
def train(self):
return self.make_dataset(self.train_df, self.train_labels)
@property
def val(self):
return self.make_dataset(self.val_df, self.val_labels)
@property
def test(self):
return self.make_dataset(self.test_df, self.test_labels)
@property
def inference(self):
return self.make_dataset(self.test_df)
@property
def example(self):
"""Get and cache an example batch of `inputs, labels` for plotting."""
result = getattr(self, "_example", None)
if result is None:
# No example batch was found, so get one from the `.train` dataset
result = next(iter(self.train))
# And cache it for next time
self._example = result
return result

View File

@ -77,9 +77,10 @@ class FreqaiDataKitchen:
self.backtest_predictions_folder: str = "backtesting_predictions" self.backtest_predictions_folder: str = "backtesting_predictions"
self.live = live self.live = live
self.pair = pair self.pair = pair
self.model_save_type = self.freqai_config.get('model_save_type', 'joblib')
self.svm_model: linear_model.SGDOneClassSVM = None self.svm_model: linear_model.SGDOneClassSVM = None
self.keras: bool = self.freqai_config.get("keras", False) # self.model_save_type: bool = self.freqai_config.get("keras", False)
self.set_all_pairs() self.set_all_pairs()
if not self.live: if not self.live:
if not self.config["timerange"]: if not self.config["timerange"]:
@ -569,7 +570,7 @@ class FreqaiDataKitchen:
predict: bool = If true, inference an existing SVM model, else construct one predict: bool = If true, inference an existing SVM model, else construct one
""" """
if self.keras: if self.model_save_type == 'keras':
logger.warning( logger.warning(
"SVM outlier removal not currently supported for Keras based models. " "SVM outlier removal not currently supported for Keras based models. "
"Skipping user requested function." "Skipping user requested function."

View File

@ -73,10 +73,10 @@ class IFreqaiModel(ABC):
self.identifier: str = self.freqai_info.get("identifier", "no_id_provided") self.identifier: str = self.freqai_info.get("identifier", "no_id_provided")
self.scanning = False self.scanning = False
self.ft_params = self.freqai_info["feature_parameters"] self.ft_params = self.freqai_info["feature_parameters"]
self.keras: bool = self.freqai_info.get("keras", False) # self.keras: bool = self.freqai_info.get("keras", False)
if self.keras and self.ft_params.get("DI_threshold", 0): # if self.keras and self.ft_params.get("DI_threshold", 0):
self.ft_params["DI_threshold"] = 0 # self.ft_params["DI_threshold"] = 0
logger.warning("DI threshold is not configured for Keras models yet. Deactivating.") # logger.warning("DI threshold is not configured for Keras models yet. Deactivating.")
self.CONV_WIDTH = self.freqai_info.get("conv_width", 2) self.CONV_WIDTH = self.freqai_info.get("conv_width", 2)
if self.ft_params.get("inlier_metric_window", 0): if self.ft_params.get("inlier_metric_window", 0):
self.CONV_WIDTH = self.ft_params.get("inlier_metric_window", 0) * 2 self.CONV_WIDTH = self.ft_params.get("inlier_metric_window", 0) * 2
@ -645,7 +645,8 @@ class IFreqaiModel(ABC):
# # for keras type models, the conv_window needs to be prepended so # # for keras type models, the conv_window needs to be prepended so
# # viewing is correct in frequi # # viewing is correct in frequi
if self.freqai_info.get('keras', False) or self.ft_params.get('inlier_metric_window', 0): if (not self.freqai_info.get('model_save_type', 'joblib') or
self.ft_params.get('inlier_metric_window', 0)):
n_lost_points = self.freqai_info.get('conv_width', 2) n_lost_points = self.freqai_info.get('conv_width', 2)
zeros_df = DataFrame(np.zeros((n_lost_points, len(hist_preds_df.columns))), zeros_df = DataFrame(np.zeros((n_lost_points, len(hist_preds_df.columns))),
columns=hist_preds_df.columns) columns=hist_preds_df.columns)

View File

@ -0,0 +1,144 @@
import logging
from typing import Any, Dict, Tuple
from pandas import DataFrame
from freqtrade.exceptions import OperationalException
from freqtrade.freqai.data_kitchen import FreqaiDataKitchen
import tensorflow as tf
from freqtrade.freqai.base_models.BaseTensorFlowModel import BaseTensorFlowModel, WindowGenerator
from tensorflow.keras.layers import Input, Conv1D, Dense
from tensorflow.keras.models import Model
import numpy as np
logger = logging.getLogger(__name__)
# tf.config.run_functions_eagerly(True)
# tf.data.experimental.enable_debug_mode()
MAX_EPOCHS = 10
class CNNPredictionModel(BaseTensorFlowModel):
"""
User created prediction model. The class needs to override three necessary
functions, predict(), fit().
"""
def fit(self, data_dictionary: Dict[str, Any], dk: FreqaiDataKitchen) -> Any:
"""
User sets up the training and test data to fit their desired model here
:params:
:data_dictionary: the dictionary constructed by DataHandler to hold
all the training and test data/labels.
"""
train_df = data_dictionary["train_features"]
train_labels = data_dictionary["train_labels"]
test_df = data_dictionary["test_features"]
test_labels = data_dictionary["test_labels"]
n_labels = len(train_labels.columns)
if n_labels > 1:
raise OperationalException(
"Neural Net not yet configured for multi-targets. Please "
" reduce number of targets to 1 in strategy."
)
n_features = len(data_dictionary["train_features"].columns)
BATCH_SIZE = self.freqai_info.get("batch_size", 64)
input_dims = [BATCH_SIZE, self.CONV_WIDTH, n_features]
w1 = WindowGenerator(
input_width=self.CONV_WIDTH,
label_width=1,
shift=1,
train_df=train_df,
val_df=test_df,
train_labels=train_labels,
val_labels=test_labels,
batch_size=BATCH_SIZE,
)
model = self.create_model(input_dims, n_labels)
steps_per_epoch = np.ceil(len(test_df) / BATCH_SIZE)
lr_schedule = tf.keras.optimizers.schedules.InverseTimeDecay(
0.001, decay_steps=steps_per_epoch * 1000, decay_rate=1, staircase=False
)
early_stopping = tf.keras.callbacks.EarlyStopping(
monitor="loss", patience=3, mode="min", min_delta=0.0001
)
model.compile(
loss=tf.losses.MeanSquaredError(),
optimizer=tf.optimizers.Adam(lr_schedule),
metrics=[tf.metrics.MeanAbsoluteError()],
)
model.fit(
w1.train,
epochs=MAX_EPOCHS,
shuffle=False,
validation_data=w1.val,
callbacks=[early_stopping],
verbose=1,
)
return model
def predict(
self, unfiltered_dataframe: DataFrame, dk: FreqaiDataKitchen, first=True
) -> Tuple[DataFrame, DataFrame]:
"""
Filter the prediction features data and predict with it.
:param: unfiltered_dataframe: Full dataframe for the current backtest period.
:return:
:predictions: np.array of predictions
:do_predict: np.array of 1s and 0s to indicate places where freqai needed to remove
data (NaNs) or felt uncertain about data (PCA and DI index)
"""
dk.find_features(unfiltered_dataframe)
filtered_dataframe, _ = dk.filter_features(
unfiltered_dataframe, dk.training_features_list, training_filter=False
)
filtered_dataframe = dk.normalize_data_from_metadata(filtered_dataframe)
dk.data_dictionary["prediction_features"] = filtered_dataframe
# optional additional data cleaning/analysis
self.data_cleaning_predict(dk, filtered_dataframe)
if first:
full_df = dk.data_dictionary["prediction_features"]
w1 = WindowGenerator(
input_width=self.CONV_WIDTH,
label_width=1,
shift=1,
test_df=full_df,
batch_size=len(full_df),
)
predictions = self.model.predict(w1.inference)
len_diff = len(dk.do_predict) - len(predictions)
if len_diff > 0:
dk.do_predict = dk.do_predict[len_diff:]
else:
data = dk.data_dictionary["prediction_features"]
data = tf.expand_dims(data, axis=0)
predictions = self.model(data, training=False)
predictions = predictions[:, 0, 0]
pred_df = DataFrame(predictions, columns=dk.label_list)
pred_df = dk.denormalize_labels_from_metadata(pred_df)
return (pred_df, np.ones(len(pred_df)))
def create_model(self, input_dims, n_labels) -> Any:
input_layer = Input(shape=(input_dims[1], input_dims[2]))
Layer_1 = Conv1D(filters=32, kernel_size=(self.CONV_WIDTH,), activation="relu")(input_layer)
Layer_3 = Dense(units=32, activation="relu")(Layer_1)
output_layer = Dense(units=n_labels)(Layer_3)
return Model(inputs=input_layer, outputs=output_layer)

View File

@ -31,6 +31,7 @@ nav:
- Running FreqAI: freqai-running.md - Running FreqAI: freqai-running.md
- Reinforcement Learning: freqai-reinforcement-learning.md - Reinforcement Learning: freqai-reinforcement-learning.md
- Developer guide: freqai-developers.md - Developer guide: freqai-developers.md
- JOSS paper: paper.md
- Short / Leverage: leverage.md - Short / Leverage: leverage.md
- Utility Sub-commands: utils.md - Utility Sub-commands: utils.md
- Plotting: plotting.md - Plotting: plotting.md