Browse Source

feat: Proportional strat

pull/19/head
QuentinN42 7 months ago
parent
commit
dc930a2e7d
Signed by: number42 GPG Key ID: 2CD7D563712B3A50
  1. 44
      auto_trading/strat/prop.py

44
auto_trading/strat/prop.py

@ -1,4 +1,4 @@
from typing import List, Dict
from typing import List, Dict, Union
import pandas as pd # type: ignore
@ -10,14 +10,23 @@ from ..errors import StrategyInitError
class Prop(Strategy):
"""Proportional repartion from the indicator."""
def __init__(self, indicators: Dict[str, Indicator] = None):
"""Init the class"""
def __init__(self, indicators: Dict[str, Indicator] = None, max_delta: float = 10):
"""Init the class.
Only have one indicator.
The max delta is the maximum difference between the actual and the desired state.
"""
if not indicators or len(indicators) != 1:
raise StrategyInitError(
"This strat must be initialized with one indicator."
)
super().__init__(indicators=indicators)
self.indicator = list(indicators.keys())[0]
self.max_delta = max_delta
def filter_order(self, order: Union[Long, Short]) -> bool:
"""Return if the order value is high enough."""
return order.amount_usd > self.max_delta
def execute(
self, data: pd.DataFrame, indicators_results: pd.DataFrame, state: PTFState
@ -34,11 +43,32 @@ class Prop(Strategy):
Returns:
List[Order]: A list of orders to execute.
"""
orders: List[Order] = []
orders: List[Union[Long, Short]] = []
conversion_rate = data.loc[data.index[-1][0]].close.to_dict()
# Desired state
results = indicators_results[self.indicator]
# TODO: Calculate the new ptf desired state from the serie
# TODO: Create the orders to match the desired state
# TODO: Filter low orders
desired_state_precent = results[results > 0] / results[results > 0].sum()
desired_state_dolards = (
state.total_balance(conversion_rate) * desired_state_precent
)
# Remove all action that the indicator place as negative.
for stock in results[results < 0].index:
orders.append(Short(stock, state.stocks[stock], conversion_rate[stock]))
# Create the new buy orders from with the delta between the actual and the desired state.
for stock, amount in desired_state_dolards.items():
if amount > state.stocks[stock]:
orders.append(
Long(stock, amount - state.stocks[stock], conversion_rate[stock])
)
else:
orders.append(
Short(stock, state.stocks[stock] - amount, conversion_rate[stock])
)
# Filter low orders
orders = list(filter(self.filter_order, orders))
return orders # type: ignore

Loading…
Cancel
Save