class A;
class B
{
public: A * a;
public: int Val;
};
class A
{
public: B * b;
public: int Test() {return b.Val + 1;}
};
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+voidOnStart()
{
B b;
A a;
b.a = GetPointer(a);
b.a.b = GetPointer(b);
b.Val = 1;
Print(b.a.Test());
}
//+------------------------------------------------------------------+// получает время открытия виртуального бара по входному времени и Таймфрейму, вне зависимости от того, существует реальный бар или нет.// корректно считает только до 28.02.2100 !!!!// не является заменой iBarShift!!! Не зависит от истории баров. datetime getStartTimeOfBarFast(ENUM_TIMEFRAMES tf, datetime t) {
if (tf==0) tf=_Period;
int ts=0;
if (tf<PERIOD_MN1) {
ushort i_tf= ushort(tf);
uchar _i =uchar(i_tf>>14);
int n = i_tf & 0x0FFF;
ts = (_i==0)?n*60:(_i==1)?n*60*60:60*60*24*7;
}
if (tf<PERIOD_W1) return t-t%ts;
if (tf==PERIOD_W1) return t-(t+4*24*60*60)%ts;
else { // Period MN1staticint dm[12] = {0,31,61,92,122,153,184, 214, 245, 275, 306, 337};
staticint last_days = 0;
staticdatetime last_result = 0;
int days = int(t/(24*60*60));
if (last_days!=days) {
last_days = days;
int d1 = (days+306+365)%1461;
int y = d1/365;
datetime t1 = t - t%(24*60*60) - d1*24*60*60;
int m = 0;
if (d1==1460) {
m=11;
y--;
};
int d = d1-y*365+1;
if (d!=31) if (d==276) m = 9;
else m = int (d/30.68);
if (m<0 || m>11) return -1;
last_result = t1+y*365*24*60*60+dm[m]*24*60*60;
}
return last_result;
}
}
//+------------------------------------------------------------------+
もし動かなくなったら、それが正しいかどうかわかるといいですね。
オブジェクトの代わりにポインターを作れば、古いバージョンでも動く。
もし動かなくなったのなら、それが正しいことなのかどうかを知るのはいいことだ。
オブジェクトの代わりにポインターを作れば、古いバージョンでも動く。
素晴らしいご指摘、ありがとうございます!
はい、確かにポインターを使えば状況は完璧に解決します:
高速アルゴリズムのファン。ナノ秒を争う人 :)
タスク: 与えられた時刻とTFに従って、バーが開く時刻を 求める。例えば、始値と終値の時間によって。
ほとんどのプログラマーは、iTime と iBarShift の組み合わせを使用します。これは最も遅い実装であり、特にこのような実装では、アップロードされたデータや結合された配列の最新の履歴が必要になります。さらに、この方法では、必要な履歴が欠落している場合にエラーが発生する可能性がある。
より高度なプログラマーは、MqlDateTime構造体とTimeToStruct()関数によってこの問題を解決するでしょう。これは悪い解決策ではないし、十分速い。
しかし、3番目の解決策があり、これは前の解決策よりも数倍生産的である:
このアルゴリズムの主な難点は、月初めの時刻を計算することです(緑色でハイライトされています)。そこには、単純なものから複雑なものへと変化するマジックがある。複雑なものから単純なものへの逆パスはもっと難しいだろう。
パフォーマンスの向上は、標準のPeriodSeconds()関数の代わりにTFからバー内の秒を取得するアルゴリズムによってももたらされます。
3つのメソッドすべてのパフォーマンスを計算し、比較するテスト・スクリプトを添付します:
iBarShiftは 実際のバーで 動作するため、iBarShiftとのチェックサムは 一致 しません。チェックサムが一致するのは、 MN1 と W1 のタイムフレームだけです。なぜなら、そのようなバーの履歴には穴がないからです。
アルゴリズムが動作を開始するときに、ループ内で小さな時間ステップ(1日未満)を使用して以前の計算を保存すると、パフォーマンスが高くなります:
iBarShift 経由のアルゴリズムで過剰な値(青くハイライトされている)は、現在必要な履歴または配列によって計算された TF がないために発生し、それらのアップロードを開始します。
アップロード後の結果は以下のようになります:
高速アルゴリズムのファン。ナノ秒を争う人たち :)
...😮😲😳🥴🤪
...
ああ...
mmm....
oooh....
gkghm...。私の素朴な疑問がこんな風に出てくるとは思わなかった。
そんな感じだ。
😮😲😳🥴🤪
...
ああ...
うーん
ああ...
えっへん。私の素朴な疑問がこんな形で出てくるとは思わなかった。
ああ。
そうだよ、アルテム、しばらく騙されたよ。
スポーツ的な興味だったんだ。
僕も含めて、誰かの役に立てばいいな。:))
そう、アルテム、君はしばらく僕をだましたね。
僕はスポーツの興味に取り組んだんだ。
誰かの役に立つことを願っているし、他の人の中でも僕の役に立つことを願っている。:))
もちろんだよ。素晴らしい。ありがとう!
S.F.これは面白かった。
その後どうするんだ?
もちろん重宝するよ素晴らしい。ありがとう!
S.F.これには驚かされました:「28.02.2100までしか正しくカウントされない!!」。
その後どうするんだ?
このアルゴリズムが75年間も需要があるとは思えない。
正直なところ、グレゴリオ暦を考慮に入れるのは怠慢だった。2000年はハイステだったが、2100年はもう違う。
このアルゴリズムが75年も需要があるとは思えない。
正直なところ、グレゴリオ暦を完全に考慮に入れるのは怠慢だった。2000年は高嶺の花だったが、2100年はもう違う。
MNについては、事前に計算された配列を使うことができる。
Ln2(12ヶ月*100年)...11のif`とバイナリサーチでの比較、しかし他の計算はない。
MNには事前に計算された配列を使えばいい。そこにデータはほとんどない。
Ln2(12ヶ月*100年)...11のif`とバイナリサーチでの比較、しかし他の計算はない。
MNには事前に計算された配列を使えばいい。そこにデータはほとんどない。
Ln2(12ヶ月*100年)...11のif`とバイナリサーチでの比較、ただし他の計算はなし。
いや、それは間違いだ。パフォーマンスを上げても効果はない。計算が滞ってしまいます。また、配列要素へのアクセスはアルゴリズムを非常に遅くする。