
이 전략은 두 개의 다른 기간의 간단한 이동 평균의 교차를 사용하여 트렌드 방향을 판단하고, 트렌드가 발생했을 때 거래합니다. 동시에, 이 전략은 다양한 시간 단위의 전략의 기대 수익을 계산하고 표시하기 위해 기대 값 패널을 도입하여 사용자가 전략의 성능을 더 잘 평가할 수 있습니다. 이 기대 값 패널은 전략의 역사적 기간 동안의 승률, 평균 수익 및 평균 손실과 같은 주요 지표를 고려하여 전략이 다양한 시장 환경에서 어떻게 수행되었는지를 직관적으로 나타냅니다.
이 전략의 핵심은 두 개의 다른 주기 (이 경우 14 일과 28 일) 의 간단한 이동 평균을 사용하여 시장의 흐름을 판단하는 것입니다. 단기 평균선이 아래에서 위쪽으로 긴 평균선을 통과하면, 시장이 상승 추세에 진입한다고 생각하면, 전략은 더 많은 포지션을 열습니다. 반대로, 단기 평균선이 위쪽으로 아래로 긴 평균선을 통과하면, 시장이 하향 추세에 진입한다고 생각하면, 전략은 포지션을 열고 공백합니다.
기본 추세 판단과 거래 논리 외에도 전략은 전략의 예상 수익을 계산하고 표시하기 위해 예상 가치 패널을 도입했습니다. 전략의 역사적 기간 동안의 주요 통계 지표에 따라 예상 가치의 계산은 다음과 같습니다.
이 지표들을 이용해서, 이 시간대에서 전략이 기대하는 값을 계산할 수 있습니다: 기대치 = 승률 × 평균 수익 - (1 - 승률) × 평균 손실
그래프에서 열 도표의 형태로 다른 시간 주기에서의 기대값을 표시함으로써 사용자는 다양한 시장 환경에서 전략의 예상 성과를 한눈에 볼 수 있으며, 전략의 적합성과 위험을 더 잘 파악할 수 있습니다.
트렌드 적응력: 이동 평균선 교차를 사용하여 트렌드를 판단하여, 이 전략은 시장의 변화에 적응하기 위해 다양한 시장 추세에서 포지션을 조기 조정할 수 있습니다. 이것은 트렌드 시장에서 이 전략이 더 나은 수익을 얻을 수있게합니다.
직관적 성능 평가: 내장된 기대값 패널은 전략이 다른 시간 주기에서 기대되는 수익을 보여주는 열 도표의 형태로 표시되며, 사용자는 다양한 시장 환경에서 전략의 성능을 한눈에 평가할 수 있습니다. 이러한 시각적 성능 표현 방식은 사용자에게 더 많은 의사 결정 참조를 제공합니다.
핵심 통계 지표를 고려합니다: 예상 값의 계산은 전략의 승률뿐만 아니라 평균 수익과 평균 손실의 영향을 통합합니다. 이러한 계산 방식은 전략의 실제 성과를 더 포괄적이고 더 정확하게 반영하여 사용자에게 더 신뢰할 수있는 참고 자료를 제공합니다.
유연한 변수 설정: 사용자가 원하는 값 패널의 표시 여부와 패널의 투명성에 따라 유연한 설정을 할 수 있습니다. 이것은 사용자가 자신의 선호에 따라 차트의 표시 효과를 조정할 수 있도록 사용 경험을 향상시킵니다.
불안한 시장에서의 부실성: 이 전략은 주로 추세에 의존하기 때문에, 불안한 시장이나 추세가 명확하지 않은 시장 환경에서, 자주 거래하는 것은 전략의 전반적인 성과에 영향을 미치는 큰 슬라이드 포인트와 거래 비용을 초래할 수 있습니다.
기대값 계산의 한계: 기대값 패널은 전략의 성능을 평가하는 직관적인 방법을 제공하지만, 여전히 역사적 데이터에 기반하여 계산합니다. 시장의 중대한 변화 또는 극단적인 상황이 발생하면, 역사적 데이터는 전략의 실제 성과를 잘 반영하지 않을 수 있으며, 기대값의 참조 의미는 떨어질 수 있습니다.
매개 변수 선택의 영향: 이 전략의 성과는 이동 평균의 주기적 선택에 크게 의존한다. 다른 주기적 조합은 완전히 다른 거래 결과를 초래할 수 있다. 선택된 매개 변수가 시장 특성에 잘 적응하지 못하면 전략의 실제 성과는 기대치와 큰 오차가 발생할 수 있다.
더 많은 기술 지표를 도입: 기존의 이동 평균을 기반으로, MACD, RSI 등과 같은 다른 기술 지표를 도입하는 것이 고려 될 수 있습니다. 트렌드의 강도와 지속성을 더 잘 판단하여 전략의 진입 및 출퇴근 시간을 향상시킬 수 있습니다.
최적화 포지션 관리: 현재 전략은 거래 신호가 발생했을 때 고정 포지션을 취한다. 시장의 변동성, 트렌드 강도 등의 요인에 따라 포지션을 동적으로 조정하는 것을 고려하여 위험을 더 잘 제어하고 수익을 높일 수 있습니다.
스톱 스톱 리스 메커니즘을 포함: 전략에 합리적인 스톱 스톱 리스 메커니즘을 포함하면, 전략이 이미 얻은 수익을 적시에 고정하는 데 도움이 될 수 있으며, 가능한 손실을 제한할 수 있습니다. 이것은 전략의 위험 수익률을 높이는 데 도움이 되며, 다양한 시장 환경에서 상대적으로 안정적인 성능을 유지할 수 있습니다.
최적화 기대값의 계산: 기대값의 계산 방법을 더 최적화 할 수 있습니다. 예를 들어 거래 비용을 고려하고 모바일 창을 도입하여 기대값 지표의 효과와 실용성을 향상시킬 수 있습니다. 또한 다른 전략 성능 평가 지표를 탐색하여 사용자에게 더 포괄적인 참고 자료를 제공할 수 있습니다.
이 전략은 이동 평균의 교차를 사용하여 시장의 추세를 판단하고, 추세가 나타났을 때 즉시 입장을 세우고, 추세에 따른 수익을 얻습니다. 동시에, 전략은 전략의 예상 수익을 여러 시간대에서 표시하는 직관적인 기대값 패널을 도입하여 사용자에게 더 많은 의사 결정 참고를 제공합니다. 전략은 불안한 시장에서 좋지 않은 성능을 발휘할 수 있으며 기대값 계산에는 한계가 있지만, 더 많은 기술 지표를 도입하고, 포지션 관리를 최적화하고, 스톱 손실 조치를 추가하면 전략의 위험 수익률을 더욱 향상시킬 수 있습니다.
/*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]