記事「ニューラルネットワークが簡単に(第52回):楽観論と分布補正の研究」についてのディスカッション - ページ 2 12 新しいコメント Dmitriy Gizlyk 2023.08.08 06:00 #11 Dmitriy Gizlyk #:Study.mq5エキスパートアドバイザーのコードにタイプミスがあることに気づきました。 記事中のファイルを更新しました。 Viktor Kudriavtsev 2023.08.14 06:15 #12 ドミトリー、なぜこのネットワークはすべてのテストで学習するとき、すべての取引を正確に1ロットでオープンし、ロットを変更しようとしないのですか?端数のロットを置こうとせず、1ロット以上を置こうともしません。EURUSDインストルメント、トレーニングパラメーターはあなたと同じです。 Dmitriy Gizlyk 2023.08.14 14:41 #13 Viktor Kudriavtsev #: ドミトリー、なぜこのネットワークは、すべてのテストで学習するとき、すべての取引を正確に1ロットでオープンし、ロットを変更しようとしないのですか?端数ロットを設定しようとせず、1ロット以上を設定しようともしません。EURUSDインストゥルメント、トレーニング・パラメーターはあなたと同じです。 最後のアクター層では、活性化関数としてシグモイドを使っています。TP と SL については、乗数を使用して値を調整する。ロットサイズは調整しない。したがって、1 ロットが可能な最大値です。 //--- レイヤー9 if(!(descr = new CLayerDescription())) return false; descr.type = defNeuronSoftActorCritic; descr.count = NActions; descr.window_out = 32; descr.optimization = ADAM; descr.activation = SIGMOID; if(!actor.Add(descr)) { delete descr; return false; } Viktor Kudriavtsev 2023.08.14 16:43 #14 Dmitriy Gizlyk #:最後のアクター層では、活性化関数としてシグモイドを使用し、値を[0,1]の範囲に制限する。TP と SL については、乗数を使用して値を調整する。ロットサイズは調整しない。したがって、1 ロットが可能な最大値です。 了解しました。 JimReaper 2023.08.15 20:34 #15 ENJOY <3 //+------------------------------------------------------------------+ //| エキスパートティック機能 //+------------------------------------------------------------------+ void OnTick() { //--- if(!IsNewBar()) を返します; //--- int bars = CopyRates(Symb.Name(), TimeFrame, iTime(Symb.Name(), TimeFrame, 1), HistoryBars, Rates); if(!ArraySetAsSeries(Rates, true)) を返す; //--- RSI.Refresh(); CCI.Refresh(); ATR.Refresh(); MACD.Refresh(); Symb.Refresh(); Symb.RefreshRates(); //--- float atr = 0; for(int b = 0; b < (int)HistoryBars; b++) { float open = (float)Rates[b].open; float rsi = (float)RSI.Main(b); float cci = (float)CCI.Main(b); atr = (float)ATR.Main(b); float macd = (float)MACD.Main(b); float sign = (float)MACD.Signal(b); if(rsi == EMPTY_VALUE || cci == EMPTY_VALUE || atr == EMPTY_VALUE || macd == EMPTY_VALUE || sign == EMPTY_VALUE) を続ける; //--- int shift = b * BarDescr; sState.state[shift] = (float)(Rates[b].close - open); sState.state[shift + 1] = (float)(Rates[b].high - open); sState.state[shift + 2] = (float)(Rates[b].low - open); sState.state[shift + 3] = (float)(Rates[b].tick_volume / 1000.0f); sState.state[shift + 4] = rsi; sState.state[shift + 5] = cci; sState.state[shift + 6] = atr; sState.state[shift + 7] = macd; sState.state[shift + 8] = sign; } bState.AssignArray(sState.state); //--- sState.account[0] = (float)AccountInfoDouble(ACCOUNT_BALANCE); sState.account[1] = (float)AccountInfoDouble(ACCOUNT_EQUITY); //--- double buy_value = 0, sell_value = 0, buy_profit = 0, sell_profit = 0; double position_discount = 0; double multiplyer = 1.0 / (60.0 * 60.0 * 10.0); int total = PositionsTotal(); datetime current = TimeCurrent(); for(int i = 0; i < total; i++) { if(PositionGetSymbol(i) != Symb.Name()) を続ける; double profit = PositionGetDouble(POSITION_PROFIT); switch((int)PositionGetInteger(POSITION_TYPE)) { case POSITION_TYPE_BUY: buy_value += PositionGetDouble(POSITION_VOLUME); buy_profit += profit; break; case POSITION_TYPE_SELL: sell_value+=PositionGetDouble(POSITION_VOLUME); sell_profit += profit; break; } position_discount += 利益 - (現在 - PositionGetInteger(POSITION_TIME))* 乗算器 * MathAbs(profit); } sState.account[2] = (float)buy_value; sState.account[3] = (float)sell_value; sState.account[4] = (float)buy_profit; sState.account[5] = (float)sell_profit; sState.account[6] = (float)position_discount; sState.account[7] = (float)Rates[0].time; //--- bAccount.Clear(); bAccount.Add((float)((sState.account[0] - PrevBalance) / PrevBalance)); bAccount.Add((float)(sState.account[1] / PrevBalance)); bAccount.Add((float)((sState.account[1] - PrevEquity) / PrevEquity)); bAccount.Add(sState.account[2]); bAccount.Add(sState.account[3]); bAccount.Add((float)(sState.account[4] / PrevBalance)); bAccount.Add((float)(sState.account[5] / PrevBalance)); bAccount.Add((float)(sState.account[6] / PrevBalance)); double x = (double)Rates[0].time / (double)(D'2024.01.01' - D'2023.01.01'); bAccount.Add((float)MathSin(x != 0 ? 2.0 * M_PI * x : 0)); x = (double)Rates[0].time / (double)PeriodSeconds(PERIOD_MN1); bAccount.Add((float)MathCos(x != 0 ? 2.0 * M_PI * x : 0)); x = (double)Rates[0].time / (double)PeriodSeconds(PERIOD_W1); bAccount.Add((float)MathSin(x != 0 ? 2.0 * M_PI * x : 0)); x = (double)Rates[0].time / (double)PeriodSeconds(PERIOD_D1); bAccount.Add((float)MathSin(x != 0 ? 2.0 * M_PI * x : 0)); //--- if (bAccount.GetIndex() >= 0 && !bAccount.BufferWrite()) を返します; //--- if (!Actor.feedForward(GetPointer(bState), 1, false, GetPointer(bAccount))) を返します; //--- PrevBalance = sState.account[0]; PrevEquity = sState.account[1]; //--- vector<float> temp; Actor.getResults(temp); float delta = MathAbs(ActorResult - temp).Sum(); ActorResult = temp; //--- double min_lot = Symb.LotsMin(); double step_lot = Symb.LotsStep(); double stops = MathMax(Symb.StopsLevel(), 1) * Symb.Point(); if (temp[0] >= temp[3]) { temp[0] -= temp[3]; temp[3] = 0; } その他 { temp[3] -= temp[0]; temp[0] = 0; } //--- コントロールを購入する if (temp[0] < min_lot || (temp[1] * MaxTP * Symb.Point()))<= 停止 || (temp[2] * MaxSL * Symb.Point())<= 停止) { if (buy_value > 0) CloseByDirection(POSITION_TYPE_BUY); } else { buy_lot = min_lot + MathRound((double)(temp[0] - min_lot) / step_lot) * step_lot; buy_tp = NormalizeDouble(Symb.Ask() + temp[1] * MaxTP * Symb.Point(), Symb.Digits()); double buy_sl = NormalizeDouble(Symb.Ask() - temp[2] * MaxSL * Symb.Point(), Symb.Digits()); if (buy_value > 0) TrailPosition(POSITION_TYPE_BUY, buy_sl, buy_tp); if (buy_value != buy_lot) { if (buy_value > buy_lot) ClosePartial(POSITION_TYPE_BUY, buy_value - buy_lot); else Trade.Buy(buy_lot - buy_value, Symb.Name(), Symb.Ask(), buy_sl, buy_tp); } } //--- コントロールを売る if (temp[3] < min_lot || (temp[4] * MaxTP * Symb.Point()))<= 停止 || (temp[5] * MaxSL * Symb.Point())<= 停止) { if (sell_value > 0) CloseByDirection(POSITION_TYPE_SELL); } else { double sell_lot = min_lot + MathRound((double)(temp[3] - min_lot) / step_lot) * step_lot; double sell_tp = NormalizeDouble(Symb.Bid() - temp[4] * MaxTP * Symb.Point(), Symb.Digits()); double sell_sl = NormalizeDouble(Symb.Bid() + temp[5] * MaxSL * Symb.Point(), Symb.Digits()); if (sell_value > 0) TrailPosition(POSITION_TYPE_SELL, sell_sl, sell_tp); if (sell_value != sell_lot) { if (sell_value > sell_lot) ClosePartial(POSITION_TYPE_SELL, sell_value - sell_lot); else Trade.Sell(sell_lot - sell_value, Symb.Name(), Symb.Bid(), sell_sl, sell_tp); } } // 初期報酬を計算する float iRewards = bAccount[0]; vector<float> log_prob; Actor.GetLogProbs(log_prob); // ATRを範囲[0, 1]に正規化する。 float minATR = -100.0; // これらの値をデータに基づいて調整する。 float maxATR = 100.0; float norm_atr = (atr - minATR) / (maxATR - minATR); // 正規化のための重みを定義する float minWeight = 0.0; float maxWeight = 1.0; // 重みに基づいて初期報酬と正規化ATRを正規化する。 float norm_iRewards = (iRewards - minWeight) / (maxWeight - minWeight); float norm_norm_atr = (norm_atr - minWeight) / (maxWeight - minWeight); // 無取引のペナルティを計算する double penalty = (buy_value + sell_value) == 0 ?(norm_norm_atr + atr / (PrevBalance + LogProbMultiplier)): 0.0; // 報酬と対数確率を更新する for (ulong i = 0; i < temp.Size(); i++) { sState.action[i] = temp[i]; sState.log_prob[i] = log_prob[i]; } // log_prob_sumに基づいてインクリメントを計算する float iRewards_increment = MathLog((float)PrevBalance); // 最初の norm_iRewards に基づいて報酬を調整する。 if (norm_iRewards != 0) { norm_iRewards += norm_norm_atr + iRewards_increment; } // norm_iRewards に Z スコアの正規化を適用する。 float meanRewards = -10.0; // 報酬の時間平均を計算する。 float stdRewards = 10.0; //報酬の標準偏差を 計算する。 float normalized_iRewards = (norm_iRewards - meanRewards) / stdRewards; // データ分布を強化するためにべき乗変換を適用する(例えば、Box-Cox変換)。 float power = 0.5; // 必要に応じて power パラメータを調整する。 float transformed_reward = (pow(1 + normalised_iRewards, power) - 1) / power; // 指数変換を適用してデータ分布を強化する float ZReward = (transformed_reward - (LogProbMultiplier)) / (5 - (LogProbMultiplier)); float Mreward = MathLog10(ZReward + 1); float reward = (Mreward - (-1.0f)) / (0.4f - (-1.0f)); 平方根変換を適用する 範囲[1、100]に戻ってマッピングされた値を計算する float SRQTreward = sqrt(reward); 報酬とその他の情報を表示する Print("Buy Value: ", buy_value); Print("Sell Value: ", sell_value); Print("温度: ", temp); Print("Temperature Size: ", temp.サイズ()); Print("iRewards: ", iRewards); Print("Normalised ATR: ", norm_norm_atr); Print("Normalized iRewards: ", normalized_iRewards); Print("Transformed Reward: ", transformed_reward); Print("Trajectory Reward: ", ZReward); Print("MATHLOG: ", Mreward); Print("Scaled Reward: ", reward); Print("SRQT Reward: ", SRQTreward); 状態と正規化された報酬を軌跡に加える if (! Base.Add(sState, reward)) { ExpertRemove(); Baseへの追加が失敗した場合の処理 } } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //|| //+------------------------------------------------------------------+ bool CreateDescriptions(CArrayObj *actor, CArrayObj *critic) { //--- CLayerDescription *descr; //--- if(!actor) { actor = new CArrayObj(); if(!actor) false を返します; } if(!critic) { critic = new CArrayObj(); if(!critic) falseを返す; } //--- 俳優 アクター.Clear(); //--- 入力レイヤー if(!(descr = new CLayerDescription())) return false; descr.type = defNeuronBaseOCL; int prev_count = descr.count = (HistoryBars * BarDescr); descr.window = 0; descr.activation=なし; descr.optimisation = ADAM; if(!actor.Add(descr)) { descrを削除します; false を返す; } //--- レイヤー1 if(!(descr = new CLayerDescription()))) return false; descr.type = defNeuronConvOCL; prev_count = descr.count = prev_count - 1; descr.window = 7; descr.step = 3; descr.window_out = 8; descr.activation = LReLU; descr.optimisation=ADAM; if(!actor.Add(descr)) { descrを削除します; false を返す; } //--- レイヤー2 if(!(descr = new CLayerDescription()))) return false; descr.type = defNeuronConvOCL; prev_count = descr.count = prev_count - 1; descr.window = 5; descr.step = 2; descr.window_out = 8; descr.activation = LReLU; descr.optimisation=ADAM; if(!actor.Add(descr)) { descrを削除します; false を返す; } //--- レイヤー3 if(!(descr = new CLayerDescription()))) return false; descr.type = defNeuronConvOCL; prev_count = descr.count = prev_count - 1; descr.window = 3; descr.step = 1; descr.window_out = 8; descr.activation = LReLU; descr.optimisation=ADAM; if(!actor.Add(descr)) { descrを削除します; false を返す; } //--- レイヤー4 if(!(descr = new CLayerDescription()))) return false; descr.type = defNeuronBaseOCL; descr.count = 1024; descr.activation = LReLU; descr.optimisation = ADAM; if(!actor.Add(descr)) { descrを削除します; false を返す; } //--- レイヤー5 if(!(descr = new CLayerDescription()))) return false; descr.type = defNeuronBaseOCL; prev_count = descr.count = 512; descr.activation = LReLU; descr.optimisation=ADAM; if(!actor.Add(descr)) { descrを削除します; false を返す; } //--- レイヤー6 if(!(descr = new CLayerDescription()))) return false; descr.type = defNeuronConvOCL; prev_count = descr.count = prev_count - 1; descr.window = 6; descr.step = 2; descr.window_out = 8; descr.activation = LReLU; descr.optimisation=ADAM; if(!actor.Add(descr)) { descrを削除します; false を返す; } //--- レイヤー7 if(!(descr = new CLayerDescription()))) return false; descr.type = defNeuronConvOCL; prev_count = descr.count = prev_count - 1; descr.window = 4; descr.step = 2; descr.window_out = 8; descr.activation = LReLU; descr.optimisation=ADAM; if(!actor.Add(descr)) { descrを削除します; false を返す; } //--- レイヤー8 if(!(descr = new CLayerDescription()))) return false; descr.type = defNeuronConvOCL; prev_count = descr.count = prev_count - 1; descr.window = 2; descr.step = 1; descr.window_out = 8; descr.activation = LReLU; descr.optimisation=ADAM; if(!actor.Add(descr)) { descrを削除します; false を返す; } //--- レイヤー9 if(!(descr = new CLayerDescription()))) return false; descr.type = defNeuronConvOCL; prev_count = descr.count = prev_count; descr.window = 8; descr.step = 8; descr.window_out = 8; descr.activation = LReLU; descr.optimisation=ADAM; if(!actor.Add(descr)) { descrを削除します; false を返す; } //--- レイヤー10 if(!(descr = new CLayerDescription()))) return false; descr.type = defNeuronBatchNormOCL; descr.count = prev_count; descr.batch = 1000; descr.activation = なし; descr.optimisation = ADAM; if(!actor.Add(descr)) { descrを削除します; false を返す; } //--- 第11層 if(!(descr = new CLayerDescription()))) return false; descr.type = defNeuronBaseOCL; descr.count = 1024; descr.activation = LReLU; descr.optimisation = ADAM; if(!actor.Add(descr)) { descrを削除します; false を返す; } //--- レイヤー12 if(!(descr = new CLayerDescription()))) return false; descr.type = defNeuronBaseOCL; prev_count = descr.count = 512; descr.activation = LReLU; descr.optimisation=ADAM; if(!actor.Add(descr)) { descrを削除します; false を返す; } //--- レイヤー13 if(!(descr = new CLayerDescription()))) return false; descr.type = defNeuronConcatenate; descr.count = LatentCount; descr.window = prev_count; descr.step = AccountDescr; descr.optimise = ADAM; descr.activation = SIGMOID; if(!actor.Add(descr)) { descrを削除します; false を返す; } //--- レイヤー14 if(!(descr = new CLayerDescription()))) return false; descr.type = defNeuronBaseOCL; descr.count = 1024; descr.activation = LReLU; descr.optimisation = ADAM; if(!actor.Add(descr)) { descrを削除します; false を返す; } //--- レイヤー15 if(!(descr = new CLayerDescription()))) return false; descr.type = defNeuronBaseOCL; prev_count = descr.count = 1024; descr.activation = LReLU; descr.optimisation = ADAM; if(!actor.Add(descr)) { descrを削除します; false を返す; } //--- レイヤー16 if(!(descr = new CLayerDescription()))) return false; descr.type = defNeuronBaseOCL; descr.count = prev_count; descr.activation = LReLU; descr.optimisation = ADAM; if(!actor.Add(descr)) { descrを削除します; false を返す; } //--- レイヤー17 if(!(descr = new CLayerDescription()))) return false; descr.type = defNeuronSoftActorCritic; descr.count = NActions; descr.window_out = 32; descr.optimise = ADAM; descr.activation = SIGMOID; if(!actor.Add(descr)) { descrを削除します; false を返す; } //--- 評論家 critic.Clear(); //--- 入力レイヤー if(!(descr = new CLayerDescription()))) return false; descr.type = defNeuronBaseOCL; prev_count = descr.count = LatentCount; descr.window = 0; descr.activation = なし; descr.optimisation = ADAM; if(!critic.Add(descr)) { descrを削除する; false を返す; } //--- レイヤー1 if(!(descr = new CLayerDescription()))) return false; descr.type = defNeuronConcatenate; descr.count = 1024; descr.window = prev_count; descr.step = 6; descr.optimise = ADAM; descr.activation = LReLU; if(!critic.Add(descr)) { descrを削除する; false を返す; } //--- レイヤー2 if(!(descr = new CLayerDescription()))) return false; descr.type = defNeuronBaseOCL; descr.count = 1024; descr.activation = LReLU; descr.optimisation = ADAM; if(!critic.Add(descr)) { descrを削除する; false を返す; } //--- レイヤー3 if(!(descr = new CLayerDescription()))) return false; descr.type = defNeuronBaseOCL; descr.count = 1024; descr.activation = LReLU; descr.optimisation = ADAM; if(!critic.Add(descr)) { descrを削除する; false を返す; } //--- レイヤー4 if(!(descr = new CLayerDescription()))) return false; descr.type = defNeuronBaseOCL; descr.count = 1024; descr.activation = LReLU; descr.optimisation = ADAM; if(!critic.Add(descr)) { descrを削除する; false を返す; } --- レイヤー5 if(!( descr = new CLayerDescription()))) false を返します; descr.type = defNeuronBaseOCL; descr.count = 1; descr.optimise = ADAM; descr.activation=なし; if(!critic.Add(descr)) { descrを削除する; false を返す; } //--- trueを返す; } Discussing the article: "Neural 記事「ニューラルネットワークが簡単に(第49回):Soft Actor-Critic」についてのディスカッション 記事「ニューラルネットワークが簡単に(第50回):Soft Actor-Critic(モデルの最適化)」についてのディスカッション JimReaper 2023.08.17 03:05 #16 ありがとう ファイル: Dmtry.PNG 34 kb 12 新しいコメント 取引の機会を逃しています。 無料取引アプリ 8千を超えるシグナルをコピー 金融ニュースで金融マーケットを探索 新規登録 ログイン スペースを含まないラテン文字 このメールにパスワードが送信されます エラーが発生しました Googleでログイン WebサイトポリシーおよびMQL5.COM利用規約に同意します。 新規登録 MQL5.com WebサイトへのログインにCookieの使用を許可します。 ログインするには、ブラウザで必要な設定を有効にしてください。 ログイン/パスワードをお忘れですか? Googleでログイン
Study.mq5エキスパートアドバイザーのコードにタイプミスがあることに気づきました。
記事中のファイルを更新しました。
ドミトリー、なぜこのネットワークは、すべてのテストで学習するとき、すべての取引を正確に1ロットでオープンし、ロットを変更しようとしないのですか?端数ロットを設定しようとせず、1ロット以上を設定しようともしません。EURUSDインストゥルメント、トレーニング・パラメーターはあなたと同じです。
最後のアクター層では、活性化関数としてシグモイドを使っています。TP と SL については、乗数を使用して値を調整する。ロットサイズは調整しない。したがって、1 ロットが可能な最大値です。
最後のアクター層では、活性化関数としてシグモイドを使用し、値を[0,1]の範囲に制限する。TP と SL については、乗数を使用して値を調整する。ロットサイズは調整しない。したがって、1 ロットが可能な最大値です。
了解しました。