"Apothéose" Je considère une expression de fxsaber, à propos de laquelle il n'a pas pu lui-même dire comment elle fonctionne, déclarant simplement que "le code a été testé à plusieurs reprises, et il fonctionne". À mon avis, cela ne devrait pas être le cas :
Ce code vérifie siun ordre otfFilingType peut êtreexécuté, et le renvoie s'il est disponible sur strSymbol, sinon il est correct.
Je n'ai absolument aucune idée de comment cela fonctionne. Et ne vous fiez qu'à l'autorité de Fxsaber.
Peut-être que quelqu'un peut expliquer ?
Pour le comprendre, il suffit de décomposer cette expression de retour encombrante en ses composantes.
d'ailleurs ce code ressemble à du spaghetti, mais vu que c'est probablement l'auteur le plus utile de kodobase en ce moment et que j'utilise moi-même ses codes tels quels, laissons quelqu'un d'autre critiquer
d'ailleurs ce code ressemble à du spaghetti, mais étant donné que c'est probablement l'auteur le plus utile de kodobase en ce moment et que j'utilise moi-même ses codes tels quels, laissons quelqu'un d'autre critiquer
il ne s'agit pas de critiquer, j'essaie de comprendre ce qu'il peut faire.... Mais comme le montre l'interview, et@fxsaber lui-même l'a admis - rien que des maux de tête.
SZZ : il est fort probable que la variante initiale du petit monstre soit plus claire ;)
Mais après cela, de plus en plus de fonctionnalités étaient nécessaires, et le code s'étoffait lentement. C'était différent avec la fonction de remplissage. Rien n'a été étoffé là-bas, tout a été écrit d'un coup.
Seul le compilateur sait exactement ce qu'il va faire. Les compilateurs modernes ont une euristique stupéfiante. Ils s'adaptent au codeur moyen et savent déjà mieux ce dont il a besoin. La meilleure chose qu'un compilateur puisse faire est d'écrire un code simple et direct avec des fonctions courtes. Il est plus facile et plus efficace pour le compilateur d'analyser le graphe du code source composé de nombreux nœuds de fonction pour construire le programme résultant. Cela n'aura qu'un effet positif sur la productivité puisque les fonctions nécessaires seront verrouillées à tous les bons endroits.
Vous avez tout à fait raison.
Si nous parlons de MQL5, vous pouvez oublier les méthodes d'"optimisation" d'il y a 10-20-30 ans. Vous devez écrire le code le plus lisible. C'est ça, et pas les trucs de hacker et de pur esprit d'initiative.
Pourquoi ?
Comme le compilateur passe par 5 à 10 cycles de réorganisation du code, il est étonnamment clair et concis, sans parler de l'utilisation de dizaines de schémas d'optimisation.
Le compilateur MQL5 s'amuse des tentatives humaines de gagner +2% de vitesse.
Si cela vous intéresse, regardez comment calculs mathématiques SQRT + se font sans branchement et une commande (128 bits de données) calcule deux racines à la fois
Ce code se transforme en code assembleur SSE suivant :
C'est une œuvre d'art en fait. 8 racines ont été calculées en 4 appels de la commande assembleur. Deux numéros doubles ont été calculés en un seul appel.
Lorsque l'on travaille dans un tableau, tout est normal, avec des contrôles, des branchements et des pertes sur la conversion d'index double -> entier.
En travaillant avec des tableaux dans cet exemple, il y a un mélange constant de FPU/ALU qui est très mauvais pour les performances.
L'optimisation de l'accès dynamique aux tableaux est formidable - au-delà des éloges. Mais mélanger les opérations FPU/ALU + double -> entier + branchement fait perdre du temps.
La conclusion générale : les mathématiques ont gagné dans MQL5 grâce à une optimisation parfaite. Ce ne sont pas les tableaux qui perdent ici, mais les mathématiques qui gagnent.
Au contraire, c'est beaucoup plus facile avec deux "si" qu'avec l'opérateur "ou".
Il est plus facile de tracer une condition en premier, et de quitter la fonction si elle est vraie, puis de vérifier l'autre condition, et de la quitter également si elle est vraie, que de deviner le résultat d'une condition complexe avec un "ou" logique (qui peut être facilement confondu avec "et"), et de tracer les deux options de retour.
C'est assez drôle de lire plus bas que "la justification d'un tel code est le débogage", car cela signifie qu'un tel code est beaucoup plus compréhensible (sinon pourquoi est-il en débogage ?).
"Apothéose" Je considère une expression de fxsaber, à propos de laquelle il n'a pas pu lui-même dire comment elle fonctionne, déclarant simplement que "le code a été testé à plusieurs reprises, et il fonctionne". À mon avis, cela ne devrait pas être le cas :
Ce code vérifie siun ordre otfFilingType peut êtreexécuté, et le renvoie s'il est disponible sur strSymbol, sinon il est correct.
Je n'ai absolument aucune idée de comment cela fonctionne. Et ne vous fiez qu'à l'autorité de Fxsaber.
Peut-être quequelqu'un peut expliquer ?
Je me suis assis une fois et je l'ai démonté étape par étape, il semble que j'ai eu besoin d'un stylo et de papier).
J'ai compris qu'en cas de changement de la structure de l'énumération, tout serait cassé, puisque des relations entières entre les valeurs de l'énumération sont utilisées (qui, selon l'idée même des énumérations, devraient être encapsulées). J'essaie moi-même d'éviter cela, tout au plus le rapport plus-moins. Pour ceux qui s'occupent de WinAPI, elle est probablement familière.
Si nous parlons de MQL5, vous pouvez oublier les méthodes d'"optimisation" d'il y a 10-20-30 ans. Vous devez écrire le code le plus lisible. C'est ça, et pas les trucs de hacker et de pur esprit d'initiative.
Exactement. Je suis arrivé à cette conclusion il y a longtemps. Mais pas parce que je pense que le compilateur le rendra meilleur. Mais parce que la principale source de problèmes dans le code est l'être humain lui-même, ce qui signifie qu'il faut écrire le code de manière à le rendre aussi simple et transparent que possible.
Si vous ne pouvez pas le rendre "transparent", vous devez écrire des commentaires détaillés expliquant pourquoi c'est comme ça et pas comme ça.
Et le compilateur... Même s'il ne le fait pas assez efficacement, c'est moins un problème qu'un bug potentiel dû au fait que vous ne prenez pas en compte certains aspects du programme.
Le code est très simple et court(description). Si vous l'écrivez sur FP, il serait intéressant de comparer.
S'il vous plaît. C# dans le style FP :
using System;
using System.Linq;
using System.Collections.Generic;
using static FeesCalculator.FeesCalcs;
using System.Text;
using static System.Math;
namespace FeesCalculator
{
publicstaticclass EnumerableExt
{
/// <summary>/// Call of function 'action' for each element if sequence (mapping)./// </summary>/// <typeparam name="T"></typeparam>/// <param name="seq">Enumerable sequence</param>/// <param name="action">Need action</param>publicstaticvoid Map<T>(this IEnumerable<T> seq, Action<T> action)
{
foreach (var item in seq)
action(item);
}
}
/// <summary>/// Инвестиционный результат/// </summary>public record AccountRecord
{
publicdouble Investor { get; init; }
publicdouble Manager { get; init; }
publicdouble Summary { get; init; }
publicstatic AccountRecord operator *(AccountRecord r, double v)
{
returnnew AccountRecord
{
Investor = r.Investor * v,
Manager = r.Manager * v,
Summary = r.Summary * v
};
}
publicoverridestring ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append(nameof(Investor)).Append(" = ").Append(Investor.ToString("F4")).Append(' ');
sb.Append(nameof(Manager)).Append(" = ").Append(Manager.ToString("F4")).Append(' ');
sb.Append(nameof(Summary)).Append(" = ").Append(Summary.ToString("F4"));
return sb.ToString();
}
}
/// <summary>/// Параметры оферты/// </summary>public record PammSet
{
/// <summary>/// Доходность за расчетный период/// </summary>publicdouble Perfomance { get; init; }
/// <summary>/// Вознаграждение управляющего/// </summary>publicdouble Gift { get; init; }
/// <summary>/// Количество расчетных периодов/// </summary>publicint N { get; init; }
/// <inheritdoc/>publicoverridestring ToString()
{
StringBuilder str = new StringBuilder();
str.Append("Доходность за расчетный период: ").Append((Perfomance * 100.0).ToString("F1")).Append("%\t\n");
str.Append("Вознаграждение управляющего: ").Append((Gift * 100.0).ToString("F1")).Append("%\t\n");
str.Append("Количество расчетных периодов: ").Append(N);
return str.ToString();
}
}
/// <summary>/// Формулы расчета/// </summary>publicclass FeesCalcs
{
/// <summary>/// Если управляющий снимает деньги в конце каждого расчетного периода/// </summary>/// <param name="Performance"></param>/// <param name="Gift"></param>/// <param name="N"></param>/// <returns></returns>publicstatic AccountRecord Set1(PammSet set)
{
Func<double> investor = () => Pow(1 + (set.Perfomance) * (1 - set.Gift), set.N);
Func<double> manager = () => (investor() - 1) * set.Gift / (1 - set.Gift);
AccountRecord ac = new AccountRecord
{
Investor = investor(),
Manager = manager(),
Summary = investor() + manager()
};
return ac;
}
/// <summary>/// Если ничего не делалось в расчетные периоды/// </summary>/// <param name="Performance"></param>/// <param name="Gift"></param>/// <param name="N"></param>/// <returns></returns>publicstatic AccountRecord Set2(PammSet set)
{
Func<double> summary = () => Pow(set.Perfomance + 1, set.N);
Func<double> manager = () => (summary() - 1) * set.Gift;
double s = summary();
double d = manager();
AccountRecord ac = new AccountRecord
{
Summary = summary(),
Manager = manager(),
Investor = summary() - manager()
};
return ac;
}
/// <summary>/// Если управляющий снимает деньги в конце каждого расчетного периода и реинвестирует их/// </summary>/// <param name="Performance"></param>/// <param name="Gift"></param>/// <param name="N"></param>/// <returns></returns>publicstatic AccountRecord Set3(PammSet set)
{
Func<double> summary = () => Pow(set.Perfomance + 1, set.N);
Func<double> investor = () => Pow(1 + (set.Perfomance) * (1 - set.Gift), set.N);
returnnew AccountRecord
{
Summary = summary(),
Investor = investor(),
Manager = summary() - investor()
};
}
/// <summary>/// Сопостовление: описание - функция расчета/// </summary>publicstatic readonly Dictionary<string, Func<PammSet, AccountRecord>> DescrToAccountRecord = new Dictionary<string, Func<PammSet, AccountRecord>>
{
{"Если управляющий снимает деньги в конце каждого расчетного периода (1)", Set1 },
{"Если ничего не делалось в расчетные периоды (2)", Set2 },
{"Если управляющий снимает деньги в конце каждого расчетного периода и реинвестирует их (3)", Set3 },
};
}
class Program
{
staticvoid Main(string[] args)
{
var _ = args.Select((a) => double.Parse(a)).Take(3).ToList();
PammSet pamm = new PammSet
{
Perfomance = _[0]/100.0,
Gift = _[1]/100.0,
N = (int)_[2]
};
Console.WriteLine($"Данные для инвестиционного счета со следующими характеристиками:\n\n{pamm}\n");
Console.WriteLine("Конечный результат для Инвестора, Управляющего и Суммарно:\n");
Func<KeyValuePair<string, Func<PammSet, AccountRecord>>, string> f = (kvp) => kvp.Key + ".\n" + kvp.Value(pamm).ToString() + "\n";
Enumerable.Select(DescrToAccountRecord, f).Map((s) => Console.WriteLine(s));
Console.WriteLine(pamm);
Func<int, PammSet> toPamm = (n) => new PammSet { Perfomance = pamm.Perfomance, Gift = pamm.Gift, N = n };
Func<PammSet, IEnumerable<AccountRecord>> toAccs = (n) => DescrToAccountRecord.Select((s) => s.Value(n));
var accounts = Enumerable.Repeat(1, pamm.N).Select((a, b) => a + b).Select(toPamm).Select(toAccs);
Func<AccountRecord, string> toString = (ar) => ar.Investor.ToString("F2") + "\t" +
ar.Manager.ToString("F2") + "\t" +
ar.Summary.ToString("F2") + "\t";
int period = default;
accounts.Map
(
(en) =>
{
Console.Write($"{++period}:\t");
en.Map((ar) =>
Console.Write(toString(ar)));
Console.WriteLine();
}
);
}
}
}
Le langage FP est bien sûr assez tordu (puisqu'il a été écrit par un codeur FP tordu, dans le langage FP incomplet C#), mais le but est de montrer qu'avec le jargon moderne de la POO, on peut aussi le faire en FP. Bien sûr, c'est limité, ce n'est pas F# ou Haskell, mais personne n'interdit d'écrire dans le style FP. Utilisez l'immuabilité, les fonctions d'ordre supérieur, les fermetures, les mappings, etc. - vous êtes le bienvenu pour tout faire. Mais cela ne rend pas le code parfait pour une raison quelconque.
s.w. La structure globale du code imite délibérément l'original. Bien que dans un bon sens il devrait être tout à fait différent dans FP, sans objets complexes et foreach imitant la carte, mais l'artiste a peint comme il pouvait.
Je comprends que c'est une question d'habitude et de connaissance de la syntaxe, mais j'ai beaucoup de mal à entrer dans le code alors que je suis l'auteur original.
#property strict#property script_show_inputsinputdouble inPerformance = 100; // Сколько процентов дает система за периодinputdouble inGift = 50; // Награда управляющего в процентах (< 100)inputint inN = 12; // Сколько расчетных периодовstruct BASE
{
double Investor;
double Manager;
double Summary;
// Если управляющий снимает деньги в конце каждого расчетного периода.void Set1( constdouble Performance, constdouble Gift, constint N )
{
this.Investor = ::MathPow(1 + (Performance - 1)* (1 - Gift), N);
this.Manager = (this.Investor - 1) * Gift / (1 - Gift);
this.Summary = this.Investor + this.Manager;
return;
}
// Если ничего не делалось в расчетные периоды.void Set2( constdouble Performance, constdouble Gift, constint N )
{
this.Summary = ::MathPow(Performance, N);
this.Manager = (this.Summary - 1) * Gift;
this.Investor = this.Summary - this.Manager;
return;
}
// Если управляющий снимает деньги в конце каждого расчетного периода и реинвестирует их.void Set3( constdouble Performance, constdouble Gift, constint N )
{
this.Summary = ::MathPow(Performance, N);
this.Investor = ::MathPow(1 + (Performance - 1)* (1 - Gift), N);
this.Manager = this.Summary - this.Investor;
return;
}
voidoperator *=( constdouble Deposit = 1 )
{
this.Investor *= Deposit;
this.Manager *= Deposit;
this.Summary *= Deposit;
return;
}
#define TOSTRING(A) #A + " = " + ::DoubleToString(A, 4) + " "string ToString( constbool FlagName = true ) const
{
return(FlagName ? TOSTRING(Investor) + TOSTRING(Manager) + TOSTRING(Summary)
: ::StringFormat("||%-12.4f||%-12.4f||%-12.4f||", this.Investor, this.Manager, this.Summary));
}
#undef TOSTRING
};
struct PAMM
{
double Performance; // Доходность за расчетный периодdouble Gift; // Вознагражение управляющего.int N; // Сколько расчетных периодов.
BASE Base1; // Если управляющий снимает деньги в конце каждого расчетного периода.
BASE Base2; // Если ничего не делалось в расчетные периоды.
BASE Base3; // Если управляющий снимает деньги в конце каждого расчетного периода и реинвестирует их.void Set( constdouble dPerformance, constdouble dGift, constint iN )
{
this.Performance = dPerformance;
this.Gift = dGift;
this.N = iN;
this.Base1.Set1(1 + this.Performance / 100, this.Gift / 100, this.N);
this.Base2.Set2(1 + this.Performance / 100, this.Gift / 100, this.N);
this.Base3.Set3(1 + this.Performance / 100, this.Gift / 100, this.N);
}
voidoperator *=( constdouble Deposit = 1 )
{
this.Base1 *= Deposit;
this.Base2 *= Deposit;
this.Base3 *= Deposit;
return;
}
string GetDescription( void ) const
{
return("Доходность за расчетный период " + ::DoubleToString(this.Performance, 1) + "%\n" +
"Вознагражение управляющего " + ::DoubleToString(this.Gift, 1) + "%\n" +
"Количество расчетных периодов. " + (string)this.N);
}
string ToString( constbool FlagName = true, constbool FlagDescription = true ) const
{
return(FlagDescription ? "Данные для инвестиционного счета со следующими характеристиками:\n\n" + this.GetDescription() +
"\n\nКонечный результат для Инвестора, Управляющего и Суммарно:""\n\nЕсли управляющий снимает деньги в конце каждого расчетного периода (1).\n" + this.Base1.ToString(FlagName) +
"\n\nЕсли ничего не делалось в расчетные периоды (2).\n" + this.Base2.ToString(FlagName) +
"\n\nЕсли управляющий снимает деньги в конце каждого расчетного периода и реинвестирует их (3).\n" + this.Base3.ToString(FlagName)
: this.Base1.ToString(FlagName) + this.Base2.ToString(FlagName) + this.Base3.ToString(FlagName));
}
};
voidOnStart()
{
PAMM Pamm;
Pamm.Set(inPerformance, inGift, inN);
Print(Pamm.ToString());
string Str = Pamm.GetDescription() + "\n ";
for (int i = 1; i <= 3; i++ )
Str += ::StringFormat("||%-12s||%-12s||%-12s||", "Investor" + (string)i, "Manager" + (string)i, "Summary" + (string)i);
for (int i = 1; i <= inN; i++ )
{
Pamm.Set(inPerformance, inGift, i);
Str += StringFormat("\n%-2d:", i) + Pamm.ToString(false, false);
}
Print(Str);
}
Techniquement, c'est probablement un OOP. Mais la partie la plus primitive de tout ça. Je ne pouvais pas le faire sans, cependant. Possible, réarrangement stupide du cerveau et rivetage de ceci.
"Apothéose" Je considère une expression de fxsaber, à propos de laquelle il n'a pas pu lui-même dire comment elle fonctionne, déclarant simplement que "le code a été testé à plusieurs reprises, et il fonctionne". À mon avis, cela ne devrait pas être le cas :
Ce code vérifie siun ordre otfFilingType peut êtreexécuté, et le renvoie s'il est disponible sur strSymbol, sinon il est correct.
Je n'ai absolument aucune idée de comment cela fonctionne. Et ne vous fiez qu'à l'autorité de Fxsaber.
Peut-être que quelqu'un peut expliquer ?
Pour le comprendre, il suffit de décomposer cette expression de retour encombrante en ses composantes.
Votre exemple de "la fin justifie les moyens".
d'ailleurs ce code ressemble à du spaghetti, mais vu que c'est probablement l'auteur le plus utile de kodobase en ce moment et que j'utilise moi-même ses codes tels quels, laissons quelqu'un d'autre critiquer
d'ailleurs ce code ressemble à du spaghetti, mais étant donné que c'est probablement l'auteur le plus utile de kodobase en ce moment et que j'utilise moi-même ses codes tels quels, laissons quelqu'un d'autre critiquer
il ne s'agit pas de critiquer, j'essaie de comprendre ce qu'il peut faire.... Mais comme le montre l'interview, et@fxsaber lui-même l'a admis - rien que des maux de tête.
SZZ : il est fort probable que la variante initiale du petit monstre soit plus claire ;)
ZS : forte probabilité que la version originale du petit monstre soit plus évidente ;)
Je l'ai pris de ZIP (contient la toute première version).
Mais après cela, de plus en plus de fonctionnalités étaient nécessaires, et le code s'étoffait lentement. C'était différent avec la fonction de remplissage. Rien n'a été étoffé là-bas, tout a été écrit d'un coup.
Seul le compilateur sait exactement ce qu'il va faire. Les compilateurs modernes ont une euristique stupéfiante. Ils s'adaptent au codeur moyen et savent déjà mieux ce dont il a besoin. La meilleure chose qu'un compilateur puisse faire est d'écrire un code simple et direct avec des fonctions courtes. Il est plus facile et plus efficace pour le compilateur d'analyser le graphe du code source composé de nombreux nœuds de fonction pour construire le programme résultant. Cela n'aura qu'un effet positif sur la productivité puisque les fonctions nécessaires seront verrouillées à tous les bons endroits.
Vous avez tout à fait raison.
Si nous parlons de MQL5, vous pouvez oublier les méthodes d'"optimisation" d'il y a 10-20-30 ans. Vous devez écrire le code le plus lisible. C'est ça, et pas les trucs de hacker et de pur esprit d'initiative.
Pourquoi ?
Comme le compilateur passe par 5 à 10 cycles de réorganisation du code, il est étonnamment clair et concis, sans parler de l'utilisation de dizaines de schémas d'optimisation.
Le compilateur MQL5 s'amuse des tentatives humaines de gagner +2% de vitesse.
C'est une œuvre d'art en fait. 8 racines ont été calculées en 4 appels de la commande assembleur. Deux numéros doubles ont été calculés en un seul appel.Si cela vous intéresse, regardez comment calculs mathématiques SQRT + se font sans branchement et une commande (128 bits de données) calcule deux racines à la fois
Ce code se transforme en code assembleur SSE suivant :
La conclusion générale : les mathématiques ont gagné dans MQL5 grâce à une optimisation parfaite. Ce ne sont pas les tableaux qui perdent ici, mais les mathématiques qui gagnent.
Pourquoi ça ?
Au contraire, c'est beaucoup plus facile avec deux "si" qu'avec l'opérateur "ou".
Il est plus facile de tracer une condition en premier, et de quitter la fonction si elle est vraie, puis de vérifier l'autre condition, et de la quitter également si elle est vraie, que de deviner le résultat d'une condition complexe avec un "ou" logique (qui peut être facilement confondu avec "et"), et de tracer les deux options de retour.
C'est assez drôle de lire plus bas que "la justification d'un tel code est le débogage", car cela signifie qu'un tel code est beaucoup plus compréhensible (sinon pourquoi est-il en débogage ?).
"Apothéose" Je considère une expression de fxsaber, à propos de laquelle il n'a pas pu lui-même dire comment elle fonctionne, déclarant simplement que "le code a été testé à plusieurs reprises, et il fonctionne". À mon avis, cela ne devrait pas être le cas :
Ce code vérifie siun ordre otfFilingType peut êtreexécuté, et le renvoie s'il est disponible sur strSymbol, sinon il est correct.
Je n'ai absolument aucune idée de comment cela fonctionne. Et ne vous fiez qu'à l'autorité de Fxsaber.
Peut-être quequelqu'un peut expliquer ?
Je me suis assis une fois et je l'ai démonté étape par étape, il semble que j'ai eu besoin d'un stylo et de papier).
J'ai compris qu'en cas de changement de la structure de l'énumération, tout serait cassé, puisque des relations entières entre les valeurs de l'énumération sont utilisées (qui, selon l'idée même des énumérations, devraient être encapsulées). J'essaie moi-même d'éviter cela, tout au plus le rapport plus-moins. Pour ceux qui s'occupent de WinAPI, elle est probablement familière.
Pour comprendre, il suffit de démonter cette expression difficile à manier qu'est le retournee.
Oui, c'est ce que j'ai essayé. Mais je n'étais pas assez motivé pour le démonter...
Tout à fait exact.
Si nous parlons de MQL5, vous pouvez oublier les méthodes d'"optimisation" d'il y a 10-20-30 ans. Vous devez écrire le code le plus lisible. C'est ça, et pas les trucs de hacker et de pur esprit d'initiative.
Exactement. Je suis arrivé à cette conclusion il y a longtemps. Mais pas parce que je pense que le compilateur le rendra meilleur. Mais parce que la principale source de problèmes dans le code est l'être humain lui-même, ce qui signifie qu'il faut écrire le code de manière à le rendre aussi simple et transparent que possible.
Si vous ne pouvez pas le rendre "transparent", vous devez écrire des commentaires détaillés expliquant pourquoi c'est comme ça et pas comme ça.
Et le compilateur... Même s'il ne le fait pas assez efficacement, c'est moins un problème qu'un bug potentiel dû au fait que vous ne prenez pas en compte certains aspects du programme.
Le code est très simple et court(description). Si vous l'écrivez sur FP, il serait intéressant de comparer.
S'il vous plaît. C# dans le style FP :
Le langage FP est bien sûr assez tordu (puisqu'il a été écrit par un codeur FP tordu, dans le langage FP incomplet C#), mais le but est de montrer qu'avec le jargon moderne de la POO, on peut aussi le faire en FP. Bien sûr, c'est limité, ce n'est pas F# ou Haskell, mais personne n'interdit d'écrire dans le style FP. Utilisez l'immuabilité, les fonctions d'ordre supérieur, les fermetures, les mappings, etc. - vous êtes le bienvenu pour tout faire. Mais cela ne rend pas le code parfait pour une raison quelconque.
s.w. La structure globale du code imite délibérément l'original. Bien que dans un bon sens il devrait être tout à fait différent dans FP, sans objets complexes et foreach imitant la carte, mais l'artiste a peint comme il pouvait.
S'il vous plaît. C# dans le style FP :
Je comprends que c'est une question d'habitude et de connaissance de la syntaxe, mais j'ai beaucoup de mal à entrer dans le code alors que je suis l'auteur original.
Forum sur le trading, les systèmes de trading automatisés et les tests de stratégie
Opinion intéressante sur la POO
fxsaber, 2021.01.29 13:39
Une bagatelle.
Techniquement, c'est probablement un OOP. Mais la partie la plus primitive de tout ça. Je ne pouvais pas le faire sans, cependant. Possible, réarrangement stupide du cerveau et rivetage de ceci.