Merge branch 'develop' into bybit
This commit is contained in:
commit
7029b9602c
@ -70,20 +70,21 @@ docker push ${CACHE_IMAGE}:$TAG_ARM
|
|||||||
# Otherwise installation might fail.
|
# Otherwise installation might fail.
|
||||||
echo "create manifests"
|
echo "create manifests"
|
||||||
|
|
||||||
docker manifest create --amend ${IMAGE_NAME}:${TAG} ${CACHE_IMAGE}:${TAG_ARM} ${IMAGE_NAME}:${TAG_PI} ${CACHE_IMAGE}:${TAG}
|
docker manifest create ${IMAGE_NAME}:${TAG} ${CACHE_IMAGE}:${TAG} ${CACHE_IMAGE}:${TAG_ARM} ${IMAGE_NAME}:${TAG_PI}
|
||||||
docker manifest push -p ${IMAGE_NAME}:${TAG}
|
docker manifest push -p ${IMAGE_NAME}:${TAG}
|
||||||
|
|
||||||
docker manifest create ${IMAGE_NAME}:${TAG_PLOT} ${CACHE_IMAGE}:${TAG_PLOT_ARM} ${CACHE_IMAGE}:${TAG_PLOT}
|
docker manifest create ${IMAGE_NAME}:${TAG_PLOT} ${CACHE_IMAGE}:${TAG_PLOT} ${CACHE_IMAGE}:${TAG_PLOT_ARM}
|
||||||
docker manifest push -p ${IMAGE_NAME}:${TAG_PLOT}
|
docker manifest push -p ${IMAGE_NAME}:${TAG_PLOT}
|
||||||
|
|
||||||
docker manifest create ${IMAGE_NAME}:${TAG_FREQAI} ${CACHE_IMAGE}:${TAG_FREQAI_ARM} ${CACHE_IMAGE}:${TAG_FREQAI}
|
docker manifest create ${IMAGE_NAME}:${TAG_FREQAI} ${CACHE_IMAGE}:${TAG_FREQAI} ${CACHE_IMAGE}:${TAG_FREQAI_ARM}
|
||||||
docker manifest push -p ${IMAGE_NAME}:${TAG_FREQAI}
|
docker manifest push -p ${IMAGE_NAME}:${TAG_FREQAI}
|
||||||
|
|
||||||
docker manifest create ${IMAGE_NAME}:${TAG_FREQAI_RL} ${CACHE_IMAGE}:${TAG_FREQAI_RL_ARM} ${CACHE_IMAGE}:${TAG_FREQAI_RL}
|
docker manifest create ${IMAGE_NAME}:${TAG_FREQAI_RL} ${CACHE_IMAGE}:${TAG_FREQAI_RL} ${CACHE_IMAGE}:${TAG_FREQAI_RL_ARM}
|
||||||
docker manifest push -p ${IMAGE_NAME}:${TAG_FREQAI_RL}
|
docker manifest push -p ${IMAGE_NAME}:${TAG_FREQAI_RL}
|
||||||
|
|
||||||
# Tag as latest for develop builds
|
# Tag as latest for develop builds
|
||||||
if [ "${TAG}" = "develop" ]; then
|
if [ "${TAG}" = "develop" ]; then
|
||||||
|
echo 'Tagging image as latest'
|
||||||
docker manifest create ${IMAGE_NAME}:latest ${CACHE_IMAGE}:${TAG_ARM} ${IMAGE_NAME}:${TAG_PI} ${CACHE_IMAGE}:${TAG}
|
docker manifest create ${IMAGE_NAME}:latest ${CACHE_IMAGE}:${TAG_ARM} ${IMAGE_NAME}:${TAG_PI} ${CACHE_IMAGE}:${TAG}
|
||||||
docker manifest push -p ${IMAGE_NAME}:latest
|
docker manifest push -p ${IMAGE_NAME}:latest
|
||||||
fi
|
fi
|
||||||
|
@ -26,7 +26,10 @@ if [ "${GITHUB_EVENT_NAME}" = "schedule" ]; then
|
|||||||
--cache-to=type=registry,ref=${CACHE_TAG} \
|
--cache-to=type=registry,ref=${CACHE_TAG} \
|
||||||
-f docker/Dockerfile.armhf \
|
-f docker/Dockerfile.armhf \
|
||||||
--platform ${PI_PLATFORM} \
|
--platform ${PI_PLATFORM} \
|
||||||
-t ${IMAGE_NAME}:${TAG_PI} --push .
|
-t ${IMAGE_NAME}:${TAG_PI} \
|
||||||
|
--push \
|
||||||
|
--provenance=false \
|
||||||
|
.
|
||||||
else
|
else
|
||||||
echo "event ${GITHUB_EVENT_NAME}: building with cache"
|
echo "event ${GITHUB_EVENT_NAME}: building with cache"
|
||||||
# Build regular image
|
# Build regular image
|
||||||
@ -35,12 +38,16 @@ else
|
|||||||
|
|
||||||
# Pull last build to avoid rebuilding the whole image
|
# Pull last build to avoid rebuilding the whole image
|
||||||
# docker pull --platform ${PI_PLATFORM} ${IMAGE_NAME}:${TAG}
|
# docker pull --platform ${PI_PLATFORM} ${IMAGE_NAME}:${TAG}
|
||||||
|
# disable provenance due to https://github.com/docker/buildx/issues/1509
|
||||||
docker buildx build \
|
docker buildx build \
|
||||||
--cache-from=type=registry,ref=${CACHE_TAG} \
|
--cache-from=type=registry,ref=${CACHE_TAG} \
|
||||||
--cache-to=type=registry,ref=${CACHE_TAG} \
|
--cache-to=type=registry,ref=${CACHE_TAG} \
|
||||||
-f docker/Dockerfile.armhf \
|
-f docker/Dockerfile.armhf \
|
||||||
--platform ${PI_PLATFORM} \
|
--platform ${PI_PLATFORM} \
|
||||||
-t ${IMAGE_NAME}:${TAG_PI} --push .
|
-t ${IMAGE_NAME}:${TAG_PI} \
|
||||||
|
--push \
|
||||||
|
--provenance=false \
|
||||||
|
.
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
@ -68,12 +75,10 @@ fi
|
|||||||
|
|
||||||
docker images
|
docker images
|
||||||
|
|
||||||
docker push ${CACHE_IMAGE}
|
docker push ${CACHE_IMAGE}:$TAG
|
||||||
docker push ${CACHE_IMAGE}:$TAG_PLOT
|
docker push ${CACHE_IMAGE}:$TAG_PLOT
|
||||||
docker push ${CACHE_IMAGE}:$TAG_FREQAI
|
docker push ${CACHE_IMAGE}:$TAG_FREQAI
|
||||||
docker push ${CACHE_IMAGE}:$TAG_FREQAI_RL
|
docker push ${CACHE_IMAGE}:$TAG_FREQAI_RL
|
||||||
docker push ${CACHE_IMAGE}:$TAG
|
|
||||||
|
|
||||||
|
|
||||||
docker images
|
docker images
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ Setting up and running a Reinforcement Learning model is the same as running a R
|
|||||||
freqtrade trade --freqaimodel ReinforcementLearner --strategy MyRLStrategy --config config.json
|
freqtrade trade --freqaimodel ReinforcementLearner --strategy MyRLStrategy --config config.json
|
||||||
```
|
```
|
||||||
|
|
||||||
where `ReinforcementLearner` will use the templated `ReinforcementLearner` from `freqai/prediction_models/ReinforcementLearner` (or a custom user defined one located in `user_data/freqaimodels`). The strategy, on the other hand, follows the same base [feature engineering](freqai-feature-engineering.md) with `feature_engineering_*` as a typical Regressor. The difference lies in the creation of the targets, Reinforcement Learning doesnt require them. However, FreqAI requires a default (neutral) value to be set in the action column:
|
where `ReinforcementLearner` will use the templated `ReinforcementLearner` from `freqai/prediction_models/ReinforcementLearner` (or a custom user defined one located in `user_data/freqaimodels`). The strategy, on the other hand, follows the same base [feature engineering](freqai-feature-engineering.md) with `feature_engineering_*` as a typical Regressor. The difference lies in the creation of the targets, Reinforcement Learning doesn't require them. However, FreqAI requires a default (neutral) value to be set in the action column:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def set_freqai_targets(self, dataframe, **kwargs):
|
def set_freqai_targets(self, dataframe, **kwargs):
|
||||||
@ -52,18 +52,18 @@ where `ReinforcementLearner` will use the templated `ReinforcementLearner` from
|
|||||||
"""
|
"""
|
||||||
# For RL, there are no direct targets to set. This is filler (neutral)
|
# For RL, there are no direct targets to set. This is filler (neutral)
|
||||||
# until the agent sends an action.
|
# until the agent sends an action.
|
||||||
df["&-action"] = 0
|
dataframe["&-action"] = 0
|
||||||
```
|
```
|
||||||
|
|
||||||
Most of the function remains the same as for typical Regressors, however, the function above shows how the strategy must pass the raw price data to the agent so that it has access to raw OHLCV in the training environment:
|
Most of the function remains the same as for typical Regressors, however, the function above shows how the strategy must pass the raw price data to the agent so that it has access to raw OHLCV in the training environment:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def feature_engineering_standard():
|
def feature_engineering_standard(self, dataframe, **kwargs):
|
||||||
# The following features are necessary for RL models
|
# The following features are necessary for RL models
|
||||||
informative[f"%-raw_close"] = informative["close"]
|
dataframe[f"%-raw_close"] = dataframe["close"]
|
||||||
informative[f"%-raw_open"] = informative["open"]
|
dataframe[f"%-raw_open"] = dataframe["open"]
|
||||||
informative[f"%-raw_high"] = informative["high"]
|
dataframe[f"%-raw_high"] = dataframe["high"]
|
||||||
informative[f"%-raw_low"] = informative["low"]
|
dataframe[f"%-raw_low"] = dataframe["low"]
|
||||||
```
|
```
|
||||||
|
|
||||||
Finally, there is no explicit "label" to make - instead it is necessary to assign the `&-action` column which will contain the agent's actions when accessed in `populate_entry/exit_trends()`. In the present example, the neutral action to 0. This value should align with the environment used. FreqAI provides two environments, both use 0 as the neutral action.
|
Finally, there is no explicit "label" to make - instead it is necessary to assign the `&-action` column which will contain the agent's actions when accessed in `populate_entry/exit_trends()`. In the present example, the neutral action to 0. This value should align with the environment used. FreqAI provides two environments, both use 0 as the neutral action.
|
||||||
@ -243,7 +243,6 @@ FreqAI also provides a built in episodic summary logger called `self.tensorboard
|
|||||||
!!! Note
|
!!! Note
|
||||||
The `self.tensorboard_log()` function is designed for tracking incremented objects only i.e. events, actions inside the training environment. If the event of interest is a float, the float can be passed as the second argument e.g. `self.tensorboard_log("float_metric1", 0.23)` would add 0.23 to `float_metric`. In this case you can also disable incrementing using `inc=False` parameter.
|
The `self.tensorboard_log()` function is designed for tracking incremented objects only i.e. events, actions inside the training environment. If the event of interest is a float, the float can be passed as the second argument e.g. `self.tensorboard_log("float_metric1", 0.23)` would add 0.23 to `float_metric`. In this case you can also disable incrementing using `inc=False` parameter.
|
||||||
|
|
||||||
|
|
||||||
### Choosing a base environment
|
### Choosing a base environment
|
||||||
|
|
||||||
FreqAI provides three base environments, `Base3ActionRLEnvironment`, `Base4ActionEnvironment` and `Base5ActionEnvironment`. As the names imply, the environments are customized for agents that can select from 3, 4 or 5 actions. The `Base3ActionEnvironment` is the simplest, the agent can select from hold, long, or short. This environment can also be used for long-only bots (it automatically follows the `can_short` flag from the strategy), where long is the enter condition and short is the exit condition. Meanwhile, in the `Base4ActionEnvironment`, the agent can enter long, enter short, hold neutral, or exit position. Finally, in the `Base5ActionEnvironment`, the agent has the same actions as Base4, but instead of a single exit action, it separates exit long and exit short. The main changes stemming from the environment selection include:
|
FreqAI provides three base environments, `Base3ActionRLEnvironment`, `Base4ActionEnvironment` and `Base5ActionEnvironment`. As the names imply, the environments are customized for agents that can select from 3, 4 or 5 actions. The `Base3ActionEnvironment` is the simplest, the agent can select from hold, long, or short. This environment can also be used for long-only bots (it automatically follows the `can_short` flag from the strategy), where long is the enter condition and short is the exit condition. Meanwhile, in the `Base4ActionEnvironment`, the agent can enter long, enter short, hold neutral, or exit position. Finally, in the `Base5ActionEnvironment`, the agent has the same actions as Base4, but instead of a single exit action, it separates exit long and exit short. The main changes stemming from the environment selection include:
|
||||||
|
@ -146,7 +146,7 @@ class Order(_DECL_BASE):
|
|||||||
# Assign funding fee up to this point
|
# Assign funding fee up to this point
|
||||||
# (represents the funding fee since the last order)
|
# (represents the funding fee since the last order)
|
||||||
self.funding_fee = self.trade.funding_fees
|
self.funding_fee = self.trade.funding_fees
|
||||||
if (order.get('filled', 0.0) or 0.0) > 0:
|
if (order.get('filled', 0.0) or 0.0) > 0 and not self.order_filled_date:
|
||||||
self.order_filled_date = datetime.now(timezone.utc)
|
self.order_filled_date = datetime.now(timezone.utc)
|
||||||
self.order_update_date = datetime.now(timezone.utc)
|
self.order_update_date = datetime.now(timezone.utc)
|
||||||
|
|
||||||
|
@ -1868,7 +1868,10 @@ def test_get_exit_order_count(fee, is_short):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("init_persistence")
|
@pytest.mark.usefixtures("init_persistence")
|
||||||
def test_update_order_from_ccxt(caplog):
|
def test_update_order_from_ccxt(caplog, time_machine):
|
||||||
|
start = datetime(2023, 1, 1, 4, tzinfo=timezone.utc)
|
||||||
|
time_machine.move_to(start, tick=False)
|
||||||
|
|
||||||
# Most basic order return (only has orderid)
|
# Most basic order return (only has orderid)
|
||||||
o = Order.parse_from_ccxt_object({'id': '1234'}, 'ADA/USDT', 'buy', 20.01, 1234.6)
|
o = Order.parse_from_ccxt_object({'id': '1234'}, 'ADA/USDT', 'buy', 20.01, 1234.6)
|
||||||
assert isinstance(o, Order)
|
assert isinstance(o, Order)
|
||||||
@ -1917,7 +1920,9 @@ def test_update_order_from_ccxt(caplog):
|
|||||||
assert o.filled == 20.0
|
assert o.filled == 20.0
|
||||||
assert o.remaining == 0.0
|
assert o.remaining == 0.0
|
||||||
assert not o.ft_is_open
|
assert not o.ft_is_open
|
||||||
assert o.order_filled_date is not None
|
assert o.order_filled_date == start
|
||||||
|
# Move time
|
||||||
|
time_machine.move_to(start + timedelta(hours=1), tick=False)
|
||||||
|
|
||||||
ccxt_order.update({'id': 'somethingelse'})
|
ccxt_order.update({'id': 'somethingelse'})
|
||||||
with pytest.raises(DependencyException, match=r"Order-id's don't match"):
|
with pytest.raises(DependencyException, match=r"Order-id's don't match"):
|
||||||
@ -1930,6 +1935,12 @@ def test_update_order_from_ccxt(caplog):
|
|||||||
|
|
||||||
# Call regular update - shouldn't fail.
|
# Call regular update - shouldn't fail.
|
||||||
Order.update_orders([o], {'id': '1234'})
|
Order.update_orders([o], {'id': '1234'})
|
||||||
|
assert o.order_filled_date == start
|
||||||
|
|
||||||
|
# Fill order again - shouldn't update filled date
|
||||||
|
ccxt_order.update({'id': '1234'})
|
||||||
|
Order.update_orders([o], ccxt_order)
|
||||||
|
assert o.order_filled_date == start
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("init_persistence")
|
@pytest.mark.usefixtures("init_persistence")
|
||||||
|
Loading…
Reference in New Issue
Block a user