Công cụ phân tích chiến lược động


Ngày tạo: 2023-10-13 15:54:35 sửa đổi lần cuối: 2023-10-13 15:54:35
sao chép: 1 Số nhấp chuột: 680
1
tập trung vào
1617
Người theo dõi

Tổng quan

Ý tưởng chính của chiến lược này là mô phỏng giao dịch trong thời gian thực, thu thập dữ liệu giao dịch hàng tuần và hiển thị kết quả thống kê dưới dạng bảng để có thể xem trực quan hơn về hiệu suất của chiến lược. Nó có thể giúp chúng ta nhanh chóng đánh giá lợi nhuận của chiến lược, tìm ra khoảng thời gian chiến lược không hoạt động tốt, điều chỉnh và tối ưu hóa chiến lược.

Nguyên tắc chiến lược

  1. Thiết lập thời gian bắt đầu và kết thúc của chu kỳ tính toán

  2. Thiết lập độ chính xác của kết quả thống kê và số tuần được bao gồm trong mỗi nhóm.

  3. Mô phỏng chiến lược RSI để mua và bán.

  4. Xác định biến trong bảng thống kê.

  5. Tính toán kết quả của chu kỳ hiện tại.

  6. Nếu chu kỳ thay đổi và cho phép giao dịch, hãy ghi lại thời gian và kết quả của chu kỳ này.

  7. Nếu là dòng K cuối cùng và cho phép giao dịch, hãy ghi lại thời gian và kết quả của chu kỳ hiện tại.

  8. Nếu chu kỳ thay đổi và không cho phép giao dịch, hãy ghi lại thời gian và kết quả của chu kỳ trước.

  9. Tìm kết quả chu kỳ cao nhất và thấp nhất.

  10. Bảng thống kê

  • Đầu tiên, tính tổng số lần thống kê

  • Đi qua mỗi chu kỳ, kết thúc, thời gian và kết quả

  • Kết quả tích lũy cho mỗi nhóm chu kỳ

  • Màu sắc cho kết quả dương tính và âm tính

Phân tích lợi thế

  • Có thể xem kết quả giao dịch hàng tuần trong thời gian thực, đánh giá nhanh hiệu quả chiến lược

  • Hiển thị trực quan kết quả, dễ dàng nhận ra các giai đoạn chiến lược kém hiệu quả

  • Các tham số chiến lược có thể được điều chỉnh và tối ưu hóa theo tình trạng lỗ hổng trong khoảng thời gian

  • Có thể dễ dàng theo dõi lợi nhuận tích lũy hàng tuần của chiến lược giữ cổ phiếu dài hạn

  • Có thể phân tích so sánh các phong cách giao dịch trong các khoảng thời gian khác nhau

  • Tính chính xác thống kê tùy chỉnh và số tuần phân nhóm để đáp ứng nhu cầu khác nhau

  • Có mã đơn giản, rõ ràng, dễ hiểu và tái phát triển

Phân tích rủi ro

  • Chiến lược này dựa trên RSI để mô phỏng giao dịch, chiến lược RSI tự nó có những nhược điểm không đủ mạnh để theo xu hướng

  • Trong thực tế, chi phí giao dịch có ảnh hưởng lớn đến kết quả.

  • Dữ liệu lịch sử được sử dụng để đánh giá không nhất thiết phải phản ánh môi trường giao dịch thực tế

  • Kết quả thống kê phụ thuộc vào số tiền trong tài khoản thực, số tiền mặc định trong phản hồi không nhất thiết phải chính xác

  • Cần chú ý để tránh quá phù hợp, thay đổi các tham số chính sách một cách mù quáng dựa trên kết quả phản hồi

Có thể kết hợp các chỉ số để đánh giá xu hướng, tối ưu hóa điểm vào và thoát, để tăng cường chiến lược RSI. Khi giao dịch thực tế, hãy chú ý đặt phí theo các tham số thực tế.

Hướng tối ưu hóa

  • Có thể xem xét thêm logic dừng lỗ để kiểm soát tổn thất đơn lẻ

  • Có thể tối ưu hóa các tham số chiến lược, chẳng hạn như điều chỉnh ngưỡng giảm giá của RSI

  • Bạn có thể thử các tần số giao dịch khác nhau, chẳng hạn như giao dịch trong ngày hoặc giữ hàng tháng

  • Có thể thêm nhiều chỉ số để đánh giá xu hướng thị trường và thời gian tham gia

  • Có thể xem xét thêm logic dừng

  • Cài đặt để tối ưu hóa các tham số thống kê

  • Có thể xem xét thực hiện thống kê trên nhiều loại tài sản

Bằng cách bổ sung các lệnh dừng lỗ, bạn có thể kiểm soát tốt hơn rủi ro và tỷ lệ lợi nhuận. Tối ưu hóa các tham số RSI có thể làm tăng tỷ lệ chiến thắng. Sử dụng nhiều chỉ số và tần số giao dịch khác nhau có thể làm cho chiến lược ổn định hơn. Điều chỉnh các tham số thống kê có thể làm cho kết quả nổi bật hơn.

Tóm tắt

Mục đích của chiến lược là thu thập kết quả giao dịch theo chu kỳ, hiển thị trực quan dưới dạng bảng thống kê, có thể nhanh chóng đánh giá lợi nhuận của chiến lược trong các khoảng thời gian khác nhau. Điều này cung cấp hỗ trợ dữ liệu cho việc tối ưu hóa chiến lược. Ưu điểm là có thể xem kết quả hàng tuần trong thời gian thực, trực quan rõ ràng, dễ dàng phát triển lần thứ hai. Cần lưu ý rằng kết quả thống kê có thể dẫn đến sự phụ thuộc quá mức và kết hợp dữ liệu phản hồi.

Mã nguồn chiến lược
/*backtest
start: 2023-09-12 00:00:00
end: 2023-10-12 00:00:00
period: 3h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
// strategy('Strategy weekly results as numbers v1', overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=25, commission_type=strategy.commission.percent, commission_value=0.04)

after = input(title='Trade after', defval=timestamp('01 Jan 2019 00:00 UTC'), tooltip="Strategy will be executed after this timestamp. The statistic table will include only periods after this date.")
before = input(title='Trade before', defval=timestamp('31 Dec 2024 23:59 UTC'), tooltip="Strategy will be executes before this timestamp. The statistic table will include only periods before this date.")

statisticPrecision = input.int(title='Statistic precision', group='Statistic visualisation', defval=1, tooltip="Defines how many digits should be rendered in every statistic cell.")
statisticGroupSize = input.int(title='Statistic group size', group='Statistic visualisation', defval=12, tooltip="Defines how many cells should be in one group inside the statistic table.")

// determinet whether the starategy should be traded between the period
isTradeEnabled = true


// *******************************************************************************************
// Core strategy simulation logic
// *******************************************************************************************
// calculate rsi strategy emulation data
rsiEmulationData = ta.rsi(close, 7)
rsiEmulationCrossover = ta.crossover(rsiEmulationData, 70)
rsiEmulationCrossunder = ta.crossunder(rsiEmulationData, 30)

// entry loogic based on the rsi calculations
if (isTradeEnabled and rsiEmulationCrossover)
    strategy.entry('Long', strategy.long)
if (isTradeEnabled and rsiEmulationCrossunder)
    strategy.entry('Short', strategy.short)


// *******************************************************************************************
// Weekly statistics table
// *******************************************************************************************
// define statistic variables
var statisticTable = table(na)
var statisticPeriodTime = array.new_int(0)
var statisticPeriodResult = array.new_float(0)
var statisticIsLatestCalculated = bool(na)
var statisticResultHighest = float(na)
var statisticResultLowest = float(na)
var statisticColorGray = color.new(color.gray, transp = 60)
var statisticColorGreen = color.new(color.green, transp = 60)
var statisticColorRed = color.new(color.red, transp = 60)

// claculate current period result
barResult = not na(strategy.equity[1])
             ? (strategy.equity / strategy.equity[1] - 1) : 0
isPeriodChanged = not na(time[1]) and weekofyear(time) != weekofyear(time[1])
currentPeriodResult = 0.0
currentPeriodResult := not na(currentPeriodResult[1]) and not isPeriodChanged
                       ? ((1 + currentPeriodResult[1]) * (1 + barResult) - 1) : 0.0

// initialise highest and lowest results variables
statisticResultHighest := na(statisticResultHighest) ? currentPeriodResult : statisticResultHighest
statisticResultLowest := na(statisticResultLowest) ? currentPeriodResult : statisticResultLowest

// search for highest and lowest results
statisticResultHighest := currentPeriodResult > statisticResultHighest ? currentPeriodResult : statisticResultHighest
statisticResultLowest := currentPeriodResult < statisticResultLowest ? currentPeriodResult : statisticResultLowest

// new week while trade is active
if isPeriodChanged and isTradeEnabled
    timeCalculated = time - 1000 * 60 * 60 * 24 * 7
    resultCalculated = currentPeriodResult[1]
    statisticIsLatestCalculated := false

    array.push(statisticPeriodTime, timeCalculated)
    array.push(statisticPeriodResult, resultCalculated)

// latest bar while trade is active
if barstate.islast and isTradeEnabled
    timeCalculated = time - 1000 * 60 * 60 * 24 * (dayofweek(time) - 2)
    resultCalculated = currentPeriodResult

    array.push(statisticPeriodTime, timeCalculated)
    array.push(statisticPeriodResult, resultCalculated)

// new week after trade disabled
if isPeriodChanged and not isTradeEnabled and not na(statisticIsLatestCalculated) and not statisticIsLatestCalculated
    timeCalculated = time - 1000 * 60 * 60 * 24 * (dayofweek(time) + 5)
    resultCalculated = currentPeriodResult[1]
    statisticIsLatestCalculated := true

    array.push(statisticPeriodTime, timeCalculated)
    array.push(statisticPeriodResult, resultCalculated)

// render statistics table
if barstate.islast
    statisticLength = array.size(statisticPeriodResult)
    statisticTableSteps = math.floor(statisticLength / statisticGroupSize) + (statisticLength % statisticGroupSize != 0 ? 1 : 0)
    statisticTable := table.new(position.bottom_right, columns = statisticGroupSize + 2, rows = statisticTableSteps + 1, border_width = 1)

    // render headers
    for i = 0 to (statisticGroupSize - 1)
        statisticHeaderContent = str.tostring(i + 1)
        table.cell(statisticTable, 1 + i, 0, statisticHeaderContent, bgcolor = statisticColorGray)

    // render time points
    for i = 0 to (statisticTableSteps - 1)
        statisticPointContent = str.format("{0,date,medium}", array.get(statisticPeriodTime, i * statisticGroupSize))
        table.cell(statisticTable, 0, 1 + i, statisticPointContent, bgcolor = statisticColorGray)

    // render the result
    statisticResultCummulative = 0.0
    for i = 0 to (array.size(statisticPeriodTime) - 1)
        statisticColumn = 1 + i % statisticGroupSize
        statisticRow = 1 + math.floor(i / statisticGroupSize)

        statisticResult = array.get(statisticPeriodResult, i)
        statisticResultCummulative := (i % statisticGroupSize == 0) ? 0.0 : statisticResultCummulative
        statisticResultCummulative := (1 + statisticResultCummulative) * (1 + statisticResult) - 1

        statisticResultColor = statisticResult > 0 ? statisticColorGreen : statisticColorRed
        table.cell(statisticTable, statisticColumn, statisticRow, str.tostring(math.round(statisticResult * 100, statisticPrecision)), bgcolor = statisticResultColor)

        // if it is the last item of the row or data array
        isStatisticLastOfTheRow = ((i + 1) % statisticGroupSize) == 0
        isStatisticLastOfTheData = i == (statisticLength - 1)
        if (isStatisticLastOfTheRow or isStatisticLastOfTheData)
            resultsTableCummulativeCellColor = statisticResultCummulative > 0 ? statisticColorGreen : statisticColorRed
            resultsTableCummulativeCellContent = str.tostring(math.round(statisticResultCummulative * 100, statisticPrecision))
            table.cell(statisticTable, 1 + statisticGroupSize, statisticRow, resultsTableCummulativeCellContent, bgcolor = resultsTableCummulativeCellColor)