
Chiến lược này sử dụng đường chéo của các đường trung bình di chuyển đơn giản trong hai chu kỳ khác nhau để đánh giá xu hướng và giao dịch khi xu hướng xuất hiện. Đồng thời, chiến lược này cũng giới thiệu một bảng giá trị mong đợi để tính toán và hiển thị lợi nhuận mong đợi của chiến lược theo các quy mô thời gian khác nhau để người dùng đánh giá tốt hơn về hiệu suất của chiến lược.
Cốt lõi của chiến lược này là sử dụng các đường trung bình di chuyển đơn giản của hai chu kỳ khác nhau (trong trường hợp này là 14 và 28 ngày) để đánh giá xu hướng thị trường. Khi đường trung bình ngắn hạn từ dưới lên xuyên qua đường trung bình dài hạn, thị trường được coi là đi vào xu hướng tăng, chiến lược mở nhiều vị trí; ngược lại, khi đường trung bình ngắn hạn từ trên xuống xuyên qua đường trung bình dài hạn, thị trường được coi là đi vào xu hướng giảm, chiến lược mở vị trí và trống. Bằng cách này, chiến lược có thể thích nghi với xu hướng thị trường khác nhau và xây dựng vị trí kịp thời khi xu hướng xuất hiện để lấy lợi nhuận từ xu hướng.
Ngoài việc phán đoán xu hướng cơ bản và logic giao dịch, chiến lược này cũng giới thiệu một bảng giá trị dự kiến để tính toán và hiển thị lợi nhuận dự kiến của chiến lược trên các quy mô thời gian khác nhau (tháng và năm). Tính toán giá trị dự kiến dựa trên các chỉ số thống kê quan trọng trong chiến lược trong khoảng thời gian lịch sử, bao gồm:
Sử dụng các chỉ số này, bạn có thể tính toán giá trị dự kiến của chiến lược trong khoảng thời gian đó: Giá trị mong đợi = tỷ lệ thắng x lợi nhuận trung bình - (1 - tỷ lệ thắng) x thua lỗ trung bình
Bằng cách hiển thị các giá trị mong đợi trong các giai đoạn thời gian khác nhau dưới dạng đồ thị nóng trên biểu đồ, người dùng có thể nhìn thấy ngay lập tức hiệu suất dự kiến của chiến lược trong các môi trường thị trường khác nhau, do đó hiểu rõ hơn về tính phù hợp và rủi ro của chiến lược.
Khả năng thích ứng với xu hướng: Bằng cách sử dụng đường trung bình di chuyển để đánh giá xu hướng, chiến lược này có thể điều chỉnh vị trí kịp thời trong các xu hướng thị trường khác nhau để thích ứng với sự thay đổi của thị trường. Điều này giúp chiến lược này có thể thu được lợi nhuận tốt hơn trong thị trường xu hướng.
Đánh giá hiệu suất trực quan: Bảng giá trị dự kiến được xây dựng trong hình ảnh đồ thị nhiệt cho thấy lợi nhuận dự kiến của chiến lược trong các chu kỳ thời gian khác nhau, người dùng có thể đánh giá trực quan hiệu suất của chiến lược trong các môi trường thị trường khác nhau. Cách trình bày hiệu suất trực quan này cung cấp cho người dùng nhiều tài liệu tham khảo quyết định hơn.
Xét các chỉ số thống kê quan trọng: Tính toán giá trị mong đợi không chỉ xem xét tỷ lệ chiến thắng của chiến lược, mà còn tổng hợp tác động của lợi nhuận trung bình và tổn thất trung bình. Cách tính toán này có thể phản ánh hiệu suất thực tế của chiến lược một cách toàn diện và chính xác hơn, cung cấp cho người dùng một tài liệu tham khảo đáng tin cậy hơn.
Cài đặt tham số linh hoạt: Người dùng có thể hiển thị hoặc không hiển thị bảng giá trị mong muốn tùy theo nhu cầu linh hoạt, và tính minh bạch của bảng. Điều này cho phép người dùng điều chỉnh hiệu ứng hiển thị của biểu đồ theo sở thích của mình, cải thiện trải nghiệm sử dụng.
Thất bại trong thị trường chấn động: Vì chiến lược này phụ thuộc nhiều vào xu hướng để thu lợi nhuận, do đó, trong thị trường chấn động hoặc môi trường thị trường không rõ xu hướng, giao dịch thường xuyên có thể dẫn đến điểm trượt và chi phí giao dịch lớn, ảnh hưởng đến hiệu suất tổng thể của chiến lược.
Hạn chế của việc tính toán giá trị kỳ vọng: Mặc dù bảng giá trị kỳ vọng cung cấp một cách trực quan để đánh giá hiệu suất chiến lược, nhưng nó vẫn được tính toán dựa trên dữ liệu lịch sử. Trong trường hợp có sự thay đổi lớn của thị trường hoặc các tình huống cực đoan, dữ liệu lịch sử có thể không phản ánh tốt hiệu suất thực tế của chiến lược và giá trị kỳ vọng có thể được giảm giá trị tham chiếu.
Lựa chọn tham số có ảnh hưởng lớn: Hiệu suất của chiến lược phụ thuộc rất nhiều vào lựa chọn chu kỳ của đường trung bình di chuyển. Các kết hợp chu kỳ khác nhau có thể mang lại kết quả giao dịch hoàn toàn khác nhau. Nếu tham số được chọn không phù hợp với đặc điểm của thị trường, hiệu suất thực tế của chiến lược có thể lệch khỏi giá trị mong đợi.
Tham gia thêm các chỉ số kỹ thuật: Dựa trên các đường trung bình di chuyển hiện có, bạn có thể xem xét việc đưa ra các chỉ số kỹ thuật khác như MACD, RSI, v.v. để đánh giá tốt hơn về sức mạnh và tính bền vững của xu hướng, do đó cải thiện thời gian nhập cảnh và xuất cảnh của chiến lược.
Quản lý vị trí tối ưu hóa: Chiến lược hiện tại áp dụng phương pháp cố định vị trí khi có tín hiệu giao dịch. Bạn có thể cân nhắc việc điều chỉnh vị trí động theo các yếu tố như biến động của thị trường, cường độ của xu hướng để kiểm soát tốt hơn rủi ro và tăng lợi nhuận.
Thêm cơ chế dừng lỗ: Thêm một cơ chế dừng lỗ hợp lý vào chiến lược có thể giúp chiến lược khóa lợi nhuận đã có kịp thời, đồng thời hạn chế tổn thất có thể. Điều này giúp tăng tỷ lệ lợi nhuận rủi ro của chiến lược, cho phép nó duy trì hiệu suất tương đối ổn định trong nhiều môi trường thị trường.
Tối ưu hóa tính toán giá trị mong muốn: Các phương pháp tính toán giá trị mong muốn có thể được tối ưu hóa hơn nữa, chẳng hạn như tính đến chi phí giao dịch, giới thiệu cửa sổ di động, v.v., để nâng cao hiệu quả và tính hữu dụng của chỉ số giá trị mong muốn. Ngoài ra, các chỉ số đánh giá hiệu suất chiến lược khác cũng có thể được khám phá để cung cấp cho người dùng một tài liệu tham khảo toàn diện hơn.
Chiến lược này sử dụng đường trung bình di chuyển để đánh giá xu hướng thị trường và đặt hàng kịp thời khi xu hướng xuất hiện để thu được lợi nhuận từ xu hướng. Đồng thời, chiến lược cũng giới thiệu một bảng giá trị kỳ vọng trực quan để hiển thị lợi nhuận kỳ vọng của chiến lược theo các quy mô thời gian khác nhau, cung cấp cho người dùng thêm tài liệu tham khảo cho quyết định. Mặc dù chiến lược có thể hoạt động kém trong thị trường bất ổn và có một số hạn chế trong tính toán giá trị kỳ vọng, nhưng bằng cách giới thiệu nhiều chỉ số kỹ thuật, tối ưu hóa quản lý vị trí và thêm các biện pháp dừng lỗ, có thể nâng cao hơn nữa so với lợi nhuận rủi ro của chiến lược, để nó có thể thích ứng tốt hơn với nhiều môi trường thị trường thay đổi.
/*backtest
start: 2023-06-11 00:00:00
end: 2024-06-16 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © ir0nantc2
//@version=5
strategy("Expected Value Panel", overlay=true)
// ロングエントリー条件 / Long entry condition
longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
if (longCondition)
strategy.entry("My Long Entry Id", strategy.long)
// ショートエントリー条件 / Short entry condition
shortCondition = ta.crossunder(ta.sma(close, 14), ta.sma(close, 28))
if (shortCondition)
strategy.entry("My Short Entry Id", strategy.short)
// ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
// Please copy the code below and paste it into the strategy where you want to display the expected value.
// 以下のコードをコピーして期待値を表示させたいストラテジーに貼り付けて下さい。
// ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
// 表示選択 / Display selection
show_performance = input.bool(true, '期待値ON/OFF (Show Expected Value)', group='Expected Value / ©ir0nantc2')
transparency = input.int(50, '透過度 (Transparency)', minval=0, maxval=100, group='Expected Value / ©ir0nantc2')
prec = 2
// 背景色 / Background color
bg_color(value) =>
na(value) ? color.new(color.gray, transparency) : value > 0.0 ? color.new(color.green, transparency) :
value < 0.0 ? color.new(color.red, transparency) :color.new(color.gray, transparency)
// 利益と損失の追跡 / Track profits and losses
var float total_monthly_profit = 0.0
var float total_yearly_profit = 0.0
if show_performance
new_month = month(time) != month(time[1])
new_year = year(time) != year(time[1])
cur_month_pnl = 0.0, cur_year_pnl = 0.0
eq = strategy.equity
bar_pnl = eq / eq[1] - 1
// 月次・年次 期待値 / Monthly & Yearly Expected Value
cur_month_pnl := new_month ? 0.0 : (1 + cur_month_pnl[1]) * (1 + bar_pnl) - 1
cur_year_pnl := new_year ? 0.0 : (1 + cur_year_pnl[1]) * (1 + bar_pnl) - 1
// 年次および月次期待値を格納 / Store monthly and yearly expected values
var month_pnl = array.new_float(), var month_time = array.new_int()
var year_pnl = array.new_float(), var year_time = array.new_int()
// 期待値計算の変数 / Variables for expected value calculation
var month_wins = array.new_int(), var month_losses = array.new_int()
var month_avg_win = array.new_float(), var month_avg_loss = array.new_float()
var year_wins = array.new_int(), var year_losses = array.new_int()
var year_avg_win = array.new_float(), var year_avg_loss = array.new_float()
// 月次および年次期待値の配列更新 / Update arrays for monthly and yearly expected values
bool last_computed = false
if (not na(cur_month_pnl[1]) and (new_month or barstate.islastconfirmedhistory))
if (last_computed and array.size(month_pnl) > 0)
array.pop(month_pnl), array.pop(month_time)
array.pop(month_wins), array.pop(month_losses)
array.pop(month_avg_win), array.pop(month_avg_loss)
array.push(month_pnl, cur_month_pnl[1]), array.push(month_time, time[1])
array.push(month_wins, 0), array.push(month_losses, 0)
array.push(month_avg_win, 0.0), array.push(month_avg_loss, 0.0)
if (not na(cur_year_pnl[1]) and (new_year or barstate.islastconfirmedhistory))
if (last_computed and array.size(year_pnl) > 0)
array.pop(year_pnl), array.pop(year_time)
array.pop(year_wins), array.pop(year_losses)
array.pop(year_avg_win), array.pop(year_avg_loss)
array.push(year_pnl, cur_year_pnl[1]), array.push(year_time, time[1])
array.push(year_wins, 0), array.push(year_losses, 0)
array.push(year_avg_win, 0.0), array.push(year_avg_loss, 0.0)
last_computed := barstate.islastconfirmedhistory ? true : last_computed
// 勝ち取引と負け取引を追跡 / Track winning and losing trades
if (strategy.closedtrades > 0 and na(strategy.closedtrades[1]) == false)
closed_profit = strategy.netprofit - strategy.netprofit[1]
if closed_profit > 0
if array.size(month_wins) > 0
wins = array.get(month_wins, array.size(month_wins) - 1) + 1
avg_win = (array.get(month_avg_win, array.size(month_avg_win) - 1) * (wins - 1) + closed_profit) / wins
array.set(month_wins, array.size(month_wins) - 1, wins)
array.set(month_avg_win, array.size(month_avg_win) - 1, avg_win)
if array.size(year_wins) > 0
wins = array.get(year_wins, array.size(year_wins) - 1) + 1
avg_win = (array.get(year_avg_win, array.size(year_avg_win) - 1) * (wins - 1) + closed_profit) / wins
array.set(year_wins, array.size(year_wins) - 1, wins)
array.set(year_avg_win, array.size(year_avg_win) - 1, avg_win)
else
if array.size(month_losses) > 0
losses = array.get(month_losses, array.size(month_losses) - 1) + 1
avg_loss = (array.get(month_avg_loss, array.size(month_avg_loss) - 1) * (losses - 1) + closed_profit) / losses
array.set(month_losses, array.size(month_losses) - 1, losses)
array.set(month_avg_loss, array.size(month_avg_loss) - 1, avg_loss)
if array.size(year_losses) > 0
losses = array.get(year_losses, array.size(year_losses) - 1) + 1
avg_loss = (array.get(year_avg_loss, array.size(year_avg_loss) - 1) * (losses - 1) + closed_profit) / losses
array.set(year_losses, array.size(year_losses) - 1, losses)
array.set(year_avg_loss, array.size(year_avg_loss) - 1, avg_loss)
// 月次テーブル / Monthly table
var monthly_table = table(na)
if (barstate.islastconfirmedhistory)
monthly_table := table.new(position.bottom_right, columns = 14, rows = array.size(year_time) + 1, border_width = 1)
table.cell(monthly_table, 0, 0, "", bgcolor = #bbbbbb00)
table.cell(monthly_table, 1, 0, "Jan", bgcolor = #bbbbbb)
table.cell(monthly_table, 2, 0, "Feb", bgcolor = #bbbbbb)
table.cell(monthly_table, 3, 0, "Mar", bgcolor = #bbbbbb)
table.cell(monthly_table, 4, 0, "Apr", bgcolor = #bbbbbb)
table.cell(monthly_table, 5, 0, "May", bgcolor = #bbbbbb)
table.cell(monthly_table, 6, 0, "Jun", bgcolor = #bbbbbb)
table.cell(monthly_table, 7, 0, "Jul", bgcolor = #bbbbbb)
table.cell(monthly_table, 8, 0, "Aug", bgcolor = #bbbbbb)
table.cell(monthly_table, 9, 0, "Sep", bgcolor = #bbbbbb)
table.cell(monthly_table, 10, 0, "Oct", bgcolor = #bbbbbb)
table.cell(monthly_table, 11, 0, "Nov", bgcolor = #bbbbbb)
table.cell(monthly_table, 12, 0, "Dec", bgcolor = #bbbbbb)
table.cell(monthly_table, 13, 0, "Year", bgcolor = #bbbbbb)
// 年次データの集計 / Collecting yearly data
var year_total_pnl = array.new_float()
var year_exp_val = array.new_float()
for yt = 0 to array.size(year_time) - 1
total_year_wins = 0, total_year_losses = 0
total_year_avg_win = 0.0, total_year_avg_loss = 0.0
total_year_pnl = 0.0
for mt = 1 to 12
idx = -1
for j = 0 to array.size(month_time) - 1
if year(array.get(month_time, j)) == year(array.get(year_time, yt)) and month(array.get(month_time, j)) == mt
idx := j
break
if idx != -1
total_year_pnl := total_year_pnl + array.get(month_pnl, idx)
total_year_wins := total_year_wins + array.get(month_wins, idx)
total_year_losses := total_year_losses + array.get(month_losses, idx)
total_year_avg_win := total_year_avg_win + (array.get(month_avg_win, idx) * array.get(month_wins, idx))
total_year_avg_loss := total_year_avg_loss + (array.get(month_avg_loss, idx) * array.get(month_losses, idx))
total_year_avg_win := total_year_wins > 0 ? total_year_avg_win / total_year_wins : 0.0
total_year_avg_loss := total_year_losses > 0 ? total_year_avg_loss / total_year_losses : 0.0
win_rate = total_year_wins + total_year_losses > 0 ? total_year_wins / (total_year_wins + total_year_losses) : na
exp_val = win_rate ? (win_rate * total_year_avg_win) - ((1 - win_rate) * math.abs(total_year_avg_loss)) : na
array.push(year_total_pnl, total_year_pnl)
array.push(year_exp_val, exp_val)
for yt = 0 to array.size(year_time) - 1
table.cell(monthly_table, 0, yt + 1, str.tostring(year(array.get(year_time, yt))), bgcolor = #bbbbbb)
y_color = bg_color(array.get(year_exp_val, yt))
value_to_display = na(array.get(year_exp_val, yt)) ? "" : str.tostring(math.round(array.get(year_exp_val, yt) * 100, prec))
table.cell(monthly_table, 13, yt + 1, value_to_display, bgcolor = y_color, text_color=color.new(color.white, 0))
for mt = 0 to array.size(month_time) - 1
m_row = year(array.get(month_time, mt)) - year(array.get(year_time, 0)) + 1
m_col = month(array.get(month_time, mt))
if array.size(month_wins) > mt and array.size(month_losses) > mt and array.size(month_avg_win) > mt and array.size(month_avg_loss) > mt
win_rate = array.get(month_wins, mt) / (array.get(month_wins, mt) + array.get(month_losses, mt))
exp_val = (win_rate * array.get(month_avg_win, mt)) - ((1 - win_rate) * math.abs(array.get(month_avg_loss, mt)))
m_color = bg_color(exp_val)
value_to_display = na(exp_val) ? "" : str.tostring(math.round(exp_val * 100, prec))
table.cell(monthly_table, m_col, m_row, value_to_display, bgcolor = m_color, text_color=color.new(color.white, 0))
else
table.cell(monthly_table, m_col, m_row, "", bgcolor = color.new(color.gray, transparency), text_color=color.new(color.white, 0))
// [EOF]