“突破策略的交易模型”

huangapple go评论64阅读模式
英文:

Trading model for breakout strategy

问题

I have reviewed your code and your goals for building a trading model. Here are some suggestions to optimize and improve the code:

  1. Modularize Code: Break down your code into smaller, reusable functions or classes. This makes it easier to understand, test, and maintain. For example, you can create separate functions for calculating metrics, finding pivot highs and lows, and determining trade entries and exits.

  2. Use Constants: Define constants for parameters such as stop loss and take profit percentages. This makes it easier to adjust these values in the future.

  3. Parameter Tuning: Consider using a parameter tuning approach to find the best values for parameters like the length of the moving average or the percentage for stop loss and take profit. This can be done using techniques like grid search or genetic algorithms.

  4. Backtesting: Implement a backtesting framework to evaluate the performance of your trading strategy. This will help you validate whether your model meets the performance goals you've set.

  5. Portfolio Management: Incorporate portfolio management techniques if you plan to trade multiple assets simultaneously. This might involve position sizing, risk management, and asset allocation strategies.

  6. Error Handling: Implement error handling to gracefully handle exceptions or unexpected data. This ensures that your code doesn't crash in real-world scenarios.

  7. Documentation: Add comments and documentation to explain the purpose of each function and the overall workflow. This makes it easier for others (and your future self) to understand and modify the code.

  8. Optimization: Depending on the size of your data, you may want to optimize certain parts of your code for performance. For example, you can explore using NumPy for vectorized calculations.

  9. Visualization: Improve the clarity of your plots by adding labels, titles, and legends. Visualizations are essential for understanding the trading strategy's behavior.

  10. Testing and Validation: Ensure that your model is thoroughly tested and validated on historical data. Be cautious of overfitting, where the model performs well on training data but poorly on new data.

  11. Risk Management: Implement robust risk management strategies, including position sizing based on risk tolerance and portfolio diversification.

  12. Alternative Approaches: Consider exploring alternative trading strategies or machine learning techniques that may better suit your goals.

  13. Data Quality: Ensure that your historical price and volume data are of high quality and free from errors or gaps.

  14. Real-time Integration: If you plan to use this model in a live trading environment, you'll need to integrate it with real-time data feeds and trading APIs. This requires additional considerations for order execution, slippage, and latency.

  15. Monitoring and Maintenance: Regularly monitor the performance of your trading model and be prepared to adapt to changing market conditions. Maintenance is an ongoing process.

Please note that building a successful trading model is a complex and challenging task, and it often requires a combination of domain expertise, data analysis, and continuous refinement. Additionally, it's essential to be aware of the risks involved in algorithmic trading and to use risk management strategies to protect your capital.

英文:

I'm trying to build a model using historical price and volume data.

Decision Variables

The model should be able to decide:

  1. When to enter a trade
  2. What type of trade to enter (Long/Short)
  3. How much SL and TP to keep for a trade
  4. When to exit a trade

Things to keep in mind

  1. The model should at no point take into consideration any future price or volume data when making a trading decision. E.g., a decision to enter trade should be purely made on the price or volume data from the past, it should have no influence of future. This is to simulate the real-world where future price or volume movements are not available anyway.
  2. The model can use multiple validations to achieve the goals
  3. Multiple time horizons can be looked at (e.g., 1-min candles, 2-min candles, 5-mins, etc.).

Goals

The overall targets to achieve through the model are:

Daily cumulative trading returns: >= 10% (cumulative = sum of all trades)

  • Sharpe Ratio: >= 3.0
  • Sortino Ratio: >= 5.0
  • Profit Factor: >= 2.0
  • Win Rate: >=75% (no. of positive trades / total trades)

Approach 1 (using TA-Lib):

import talib as ta
import math
import matplotlib.pyplot as plt

# Parameters
length = 14
k = 1.0
method = 'Atr'
show = False

# Data
# Replace [...] with your price and volume data
close = [...]
high = [...]
low = [...]
volume = [...]

# Calculate pivot highs and lows
ph = find_pivot_highs(high, length)
pl = find_pivot_lows(low, length)


def find_pivot_highs(data, length):
    pivot_highs = []
    for i in range(length, len(data) - length):
        if (
            data[i] > max(data[i - length : i])
            and data[i] > max(data[i + 1 : i + length + 1])
        ):
            pivot_highs.append(i)
    return pivot_highs


def find_pivot_lows(data, length):
    pivot_lows = []
    for i in range(length, len(data) - length):
        if (
            data[i] < min(data[i - length : i])
            and data[i] < min(data[i + 1 : i + length + 1])
        ):
            pivot_lows.append(i)
    return pivot_lows


# Calculate slope
def calculate_slope():
    if method == 'Atr':
        return ta.ATR(high, low, close, length) / length * k
    elif method == 'Stdev':
        return ta.STDDEV(src, length) / length * k
    elif method == 'Linreg':
        sma1 = ta.SMA(src * n, length)
        sma2 = ta.SMA(src, length)
        return math.fabs(sma1 - sma2 * ta.SMA(n, length)) / ta.VAR(n, length) / 2 * k


slope = calculate_slope()

slope_ph = [slope[i] if i in ph else slope_ph[i-1] for i in range(len(close))]
slope_pl = [slope[i] if i in pl else slope_pl[i-1] for i in range(len(close))]

upper = [ph[i] if i in ph else upper[i-1] - slope_ph[i] for i in range(len(close))]
lower = [pl[i] if i in pl else lower[i-1] + slope_pl[i] for i in range(len(close))]

# ----
single_upper = [0] * len(close)
single_lower = [0] * len(close)

for i in range(length, len(close)):
    if close[i] > upper[i-length]:
        single_upper[i] = 1
    elif i in ph:
        single_upper[i] = single_upper[i-1]

    if close[i] < lower[i-length]:
        single_lower[i] = 1
    elif i in pl:
        single_lower[i] = single_lower[i-1]

upper_breakout = [
    single_upper[i-1] and close[i] > upper[i] and (show or close[i] > close[i-length])
    for i in range(len(close))
]

lower_breakout = [
    single_lower[i-1] and close[i] < lower[i] and (show or close[i] < close[i-length])
    for i in range(len(close))
]

# Trading strategy
trades = []
trade_type = None
entry_price = None
stop_loss = None
take_profit = None

for i in range(len(close)):
    if trade_type is None:
        if upper_breakout[i]:
            trade_type = 'Long'
            entry_price = close[i]
            stop_loss = entry_price - 0.02 * entry_price  # Example stop loss calculation
            take_profit = entry_price + 0.03 * entry_price  # Example take profit calculation
        elif lower_breakout[i]:
            trade_type = 'Short'
            entry_price = close[i]
            stop_loss = entry_price + 0.02 * entry_price  # Example stop loss calculation
            take_profit = entry_price - 0.03 * entry_price  # Example take profit calculation
    else:
        if trade_type == 'Long':
            if close[i] <= stop_loss or close[i] >= take_profit:
                trades.append((entry_price, stop_loss, take_profit))
                trade_type = None
                entry_price = None
                stop_loss = None
                take_profit = None
        elif trade_type == 'Short':
            if close[i] >= stop_loss or close[i] <= take_profit:
                trades.append((entry_price, stop_loss, take_profit))
                trade_type = None
                entry_price = None
                stop_loss = None
                take_profit = None

# Calculate metrics
total_trades = len(trades)
positive_trades = sum(1 for t in trades if t[2] > t[0])
win_rate = positive_trades / total_trades if total_trades > 0 else 0

cumulative_returns = sum((t[2] - t[0]) / t[0] for t in trades)
sharpe_ratio = (cumulative_returns - 0.01) / (cumulative_returns.std() + 1e-9)
sortino_ratio = (cumulative_returns - 0.01) / (cumulative_returns[cumulative_returns < 0].std() + 1e-9)
profit_factor = sum(t[2] - t[0] for t in trades if t[2] > t[0]) / abs(sum(t[2] - t[0] for t in trades if t[2] < t[0]))

# Print metrics
print(f"Total Trades: {total_trades}")
print(f"Positive Trades: {positive_trades}")
print(f"Win Rate: {win_rate * 100}%")
print(f"Cumulative Returns: {cumulative_returns * 100}%")
print(f"Sharpe Ratio: {sharpe_ratio}")
print(f"Sortino Ratio: {sortino_ratio}")
print(f"Profit Factor: {profit_factor}")

# Plotting
plt.plot(close[length:], label='Closing Price')
plt.plot(upper[length:], label='Upper Trendline', color='#26a69a')
plt.plot(lower[length:], label='Lower Trendline', color='#ef5350')

for i in range(len(close)):
    if upper_breakout[i]:
        plt.scatter(i, close[i-length], marker='^', color='r', label='Upper Break')
    if lower_breakout[i]:
        plt.scatter(i, close[i-length], marker='v', color='g', label='Lower Break')

plt.legend()
plt.show()

Approach 2 (using pandas_ta):

import pandas as pd
import pandas_ta as ta
import matplotlib.pyplot as plt
import numpy as np

# Load your price data into a pandas DataFrame
data = pd.read_csv('your_data.csv')
close = data['close']
high = data['high']
low = data['low']

length = 14
k = 1.0
method = 'Atr'
show = False

# Calculate the indicators using pandas-ta
data['atr'] = ta.atr(high, low, close, length)
data['stddev'] = ta.stddev(close, length)
data['sma1'] = ta.sma(close, length)
data['sma2'] = ta.sma(close, length)
data['var'] = ta.var(close, length)
data['n'] = data.index

data['slope'] = 0.0
data['slope'] = np.where(method == 'Atr', data['atr'] / length * k,
                         np.where(method == 'Stdev', data['stddev'] / length * k,
                                  np.where(method == 'Linreg', data['sma1'] - data['sma2'] * data['n'] / data['var'] / 2 * k)))
#data.loc[method == 'Atr', 'slope'] = data['atr'] / length * k
#data.loc[method == 'Stdev', 'slope'] = data['stddev'] / length * k
#data.loc[method == 'Linreg', 'slope'] = (data['sma1'] - data['sma2'] * data['n']) / data['var'] / 2 * k

# Find pivot highs and lows
data['ph'] = ta.pivot_high(high, length)
data['pl'] = ta.pivot_low(low, length)

data['slope_ph'] = data['slope'].where(data.index.isin(data['ph'])).ffill()
data['slope_pl'] = data['slope'].where(data.index.isin(data['pl'])).ffill()

data['upper'] = data['ph'].where(data.index.isin(data['ph'])).ffill() - data['slope_ph']
data['lower'] = data['pl'].where(data.index.isin(data['pl'])).ffill() + data['slope_pl']

# Determine trade entries and exits
data['trade_type'] = None
data['entry_price'] = None
data['stop_loss'] = None
data['take_profit'] = None

for i in range(length, len(data)):
    if data['close'][i] > data['upper'][i-length]:
        data['trade_type'][i] = 'Long'
        data['entry_price'][i] = data['close'][i]
        data['stop_loss'][i] = data['entry_price'][i] - 0.02 * data['entry_price'][i]
        data['take_profit'][i] = data['entry_price'][i] + 0.03 * data['entry_price'][i]
    elif data['close'][i] < data['lower'][i-length]:
        data['trade_type'][i] = 'Short'
        data['entry_price'][i] = data['close'][i]
        data['stop_loss'][i] = data['entry_price'][i] + 0.02 * data['entry_price'][i]
        data['take_profit'][i] = data['entry_price'][i] - 0.03 * data['entry_price'][i]

data['trade_type'] = data['trade_type'].ffill()
data['entry_price'] = data['entry_price'].ffill()
data['stop_loss'] = data['stop_loss'].ffill()
data['take_profit'] = data['take_profit'].ffill()

data['exit_trade'] = False
for i in range(length, len(data)):
    if (
        (data['trade_type'][i] == 'Long' and data['low'][i] < data['stop_loss'][i]) or
        (data['trade_type'][i] == 'Short' and data['high'][i] > data['stop_loss'][i])
    ):
        data['exit_trade'][i] = True

# Calculate trading metrics
total_trades = len(data[data['entry_price'].notnull()])
positive_trades = len(data[(data['entry_price'].notnull()) & (data['close'] > data['entry_price'])])
win_rate = positive_trades / total_trades if total_trades > 0 else 0.0

# Plotting
plt.plot(data['close'][length:], label='Closing Price')
plt.plot(data['upper'][length:], label='Upper Trendline', color='#26a69a')
plt.plot(data['lower'][length:], label='Lower Trendline', color='#ef5350')

for i in range(len(data)):
    if not pd.isnull(data['entry_price'][i]):
        if data['trade_type'][i] == 'Long':
            plt.scatter(i, data['entry_price'][i], marker='^', color='r', label='Long Entry')
        else:
            plt.scatter(i, data['entry_price'][i], marker='v', color='g', label='Short Entry')
    if data['exit_trade'][i]:
        plt.scatter(i, data['stop_loss'][i], marker='x', color='b', label='Exit')

plt.legend()
plt.show()

I need suggestions about how to incorporate all the goals and make the code, more optimized and better.

Cheers!

答案1

得分: 1

尝试使用 pandas-ta 这个库,它比 ta-lib 更轻量和更快。

英文:

Try using pands-ta the library is lighter and faster than ta-lib

huangapple
  • 本文由 发表于 2023年5月25日 13:45:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76329243.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定