আগের নিবন্ধেআপনাকে কৌশল লিখতে শেখাবে -- মাই ল্যাঙ্গুয়েজের কৌশল প্রতিস্থাপন করবে, একটি সহজ মাইল্যাঙ্গুয়েজ কৌশল প্রতিস্থাপনের জন্য পরীক্ষা করা হয়েছে। যদি এটি একটি জটিল মাইল্যাঙ্গুয়েজ হয়, তাহলে এটি একটি জাভাস্ক্রিপ্ট ভাষা কৌশলতে কিভাবে প্রতিস্থাপন করা যায়? কোন দক্ষতা আছে?
আসুন প্রথমে ট্রান্সপ্ল্যান্ট করার কৌশলটি দেখিঃ
(*backtest
start: 2019-05-01 00:00:00
end: 2019-11-12 00:00:00
period: 1d
exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"}]
args: [["SlideTick",10,126961],["ContractType","quarter",126961]]
*)
N1:=10;
N2:=21;
AP:=(HIGH+LOW+CLOSE)/3;
ESA:=EMA(AP,N1);
D:=EMA(ABS(AP-ESA),N1);
CI:=(AP-ESA)/(0.015*D);
TCI:=EMA(CI,N2);
WT1:TCI;
WT2:SMA(WT1,4,1);
AA:=CROSS(WT1,WT2);
BB:=CROSSDOWN(WT1,WT2);
REF(AA,1),BPK;
REF(BB,1),SPK;
দ্য(* backtest... *)
MyLanguage কৌশল শুরুতে ব্যাকটেস্টিং সেটিংস জন্য কনফিগারেশন কোড হয়। তুলনা সহজ করার জন্য, একটি ইউনিফাইড ব্যাকটেস্টিং কনফিগারেশন সেট করা হয়। এই কৌশলটি একটি এলোমেলো এক, যা খুব জটিল নয় (গত নিবন্ধে যে তুলনায় আরো জটিল) । এটি একটি প্রতিনিধিত্বমূলক কৌশল। একটি MyLanguage কৌশল প্রতিস্থাপন করার জন্য, আপনি প্রথম পুরো কৌশল তাকান উচিত। কৌশল কোড সংক্ষিপ্ত, এবং আপনি সামগ্রিক কৌশল একটি নির্দিষ্ট বোঝার থাকতে পারে। এই কৌশল জন্য আমরা দেখেছি যে বেশ কয়েকটি সূচক ফাংশনEMA
, SMA
ব্যবহার করা হয়েছেঃ
ইএমএ
সূচক ফাংশন, জাভাস্ক্রিপ্ট ভাষায় কৌশল লেখার সময় সরাসরি এফএমজেড প্ল্যাটফর্মে উপলব্ধ রেডিমেড সূচক লাইব্রেরি ফাংশন রয়েছে। অর্থাৎঃTA.MA
.
এসএমএ
আমাদের যা করতে হবে তা হলSMA
সূচক, যা আমরা FMZ এর TA লাইব্রেরিতে খুঁজে পেয়েছি SMA সূচক ফাংশন সমর্থন করে না, এবং তালেব লাইব্রেরিতে SMA সূচক এবং মাইল্যাঙ্গুয়েজের মধ্যে পার্থক্য রয়েছে।
আমরা দেখতে পাচ্ছি, প্যারামিটার বিভাগে পেরিওড প্যারামিটার ছাড়াও একটি ওজন প্যারামিটার রয়েছে।
এফএমজেড এপিআই ডকুমেন্টেশনে তালিব লাইব্রেরিতে এসএমএ সূচক ফাংশনটি নিম্নরূপ বর্ণনা করা হয়েছেঃ
এটা দেখা যাচ্ছে যেtalib.SMA
একটি সহজ চলমান গড়ের সূচক।
এইভাবে, আমরা কেবল নিজেরাই একটি এসএমএ বাস্তবায়ন করতে পারি। কৌশল লেখার জন্য জাভাস্ক্রিপ্ট ভাষা ব্যবহার করে ডেভেলপার হিসাবে, এটিও প্রয়োজনীয় দক্ষতার মধ্যে একটি। সব পরে, যদি কোনও প্রস্তুত চাকা না থাকে তবে প্রোগ্রামটি এখনও চালানো দরকার, কেবল একটি তৈরি করুন।
প্রকৃতপক্ষে, সূচক ইত্যাদি সম্পর্কে খুব বেশি গবেষণা নেই। সাধারণভাবে, লোকেরা যদি এটি বুঝতে না পারে তবে তারা তথ্য অনুসন্ধান করে। এসএমএ এর জন্য এগুলি খুঁজে পেতেঃ
মনে হচ্ছে এই তত্ত্বের অ্যালগরিদম প্রক্রিয়াটি বেশ নির্ভরযোগ্য, এবং বাস্তবায়নটি নিম্নরূপঃ
function SMA (arr, n, m) {
var sma = []
var currSMA = null
for (var i = 0; i < arr.length; i++) {
if (arr[i] && !isNaN(arr[i])) {
if (!currSMA) {
currSMA = arr[i]
sma.push(currSMA)
continue
}
// [M*C2+(N-M)*S1]/N
currSMA = (m * arr[i] + (n - m) * currSMA) / n
sma.push(currSMA)
} else {
sma.push(NaN)
}
}
return sma
}
কৌশলগত কাঠামোটি নিবন্ধের মতো একই কাঠামো ব্যবহার করে।আপনাকে কৌশল লিখতে শেখাবে -- মাই ল্যাঙ্গুয়েজের কৌশল প্রতিস্থাপন করবেএবং মূলত দুটি অংশে ভরাঃ
প্রথমে, টিকার ডেটা প্রসেসিং এবং ইনডেক্স গণনা করুন।
চলুন MyLanguage এর এই অংশটি একবারে একটি বাক্য, ফাংশন দ্বারা ফাংশন নিয়ে নিইঃ
AP:=(HIGH+LOW+CLOSE)/3;
এটা বোঝা যায় যে K রেখার তথ্যে প্রতিটি BAR এর সর্বোচ্চ মূল্য, সর্বনিম্ন মূল্য এবং বন্ধের মূল্য যোগ করা উচিত এবং তারপর 3 দ্বারা বিভক্ত করা উচিত যাতে গড় মান গণনা করা যায় এবং তারপর একটি অ্যারে হিসাবে সংরক্ষণ করা উচিত, যা প্রতিটি BAR এর সাথে একের পর এক মিলে যায়। এটি নিম্নরূপ প্রক্রিয়া করা যেতে পারেঃ
function CalcAP (r) { // AP:=(HIGH+LOW+CLOSE)/3;
var arrAP = [] // Declare an empty array
for (var i = 0; i < r.length; i++) { // r is the incoming K-line data, which is an array, use for to traverse this array.
v = (r[i].High + r[i].Low + r[i].Close) / 3 // Calculate the average value.
arrAP.push(v) // Add to the end of the arrAP array, the end is the first when arrAP is empty.
}
return arrAP // Returns this average array, i.e., the AP calculated in the MyLanguage
}
এই ফাংশনটি প্রধান লুপ OnTick ফাংশনে কল করা যেতে পারে, উদাহরণস্বরূপঃ
// Calculation of indicators
// AP
var ap = CalcAP(records)
ESA:=EMA(AP,N1);
:এখানে, আমরা পূর্ববর্তী ধাপে গণনা করা এপি এর তথ্য ব্যবহার করব ইএসএ গণনা করার জন্য। আসলে, ইএসএ হল এপি এর
function CalcESA (ap, n1) { // ESA:=EMA(AP,N1);
if (ap.length <= n1) { // If the AP length is less than the indicator parameter, valid data cannot be calculated. At this time, let the function return false.
return false
}
return TA.EMA(ap, n1)
}
D:=EMA(ABS(AP-ESA),N1);
হিসাব করা ব্যবহার করুনAP
, ESA
তথ্য গণনা করতেD
..
সূচকগুলি কিভাবে গণনা করা যায় সে সম্পর্কে কিছু টিপস পেতে এখানে কোড মন্তব্যগুলি পড়তে পারেন।
function CalcD (ap, esa, n1) { // D:=EMA(ABS(AP-ESA),N1);
var arrABS_APminusESA = []
if (ap.length != esa.length) {
throw "ap.length != esa.length"
}
for (var i = 0; i < ap.length; i++) {
// When calculating the value of the indicator, it is necessary to determine the validity of the data, because the first few EMA calculations may be the beginning of the array of data is NaN, or null.
// So it must be judged that the data involved in the calculation are all valid values to proceed, and if there are any invalid values, they are filled with NaN to arrABS_APminusESA.
// The data thus calculated, each position corresponds to the previous data one by one, without misalignment.
if (ap[i] && esa[i] && !isNaN(ap[i]) && !isNaN(esa[i])) {
v = Math.abs(ap[i] - esa[i]) // According to ABS(AP-ESA), the specific value is calculated and put into the arrABS_APminusESA array.
arrABS_APminusESA.push(v)
} else {
arrABS_APminusESA.push(NaN)
}
}
if (arrABS_APminusESA.length <= n1) {
return false
}
return TA.EMA(arrABS_APminusESA, n1) // Calculate the EMA indicator of the array arrABS_APminusESA and get the data D (array structure).
}
CI:=(AP-ESA)/(0.015*D);
হিসাব পদ্ধতিটি ধাপ ১ এর অনুরূপ এবং কোডটি সরাসরি প্রকাশ করা হয়।function CalcCI (ap, esa, d) { // CI:=(AP-ESA)/(0.015*D);
var arrCI = []
if (ap.length != esa.length || ap.length != d.length) {
throw "ap.length != esa.length || ap.length != d.length"
}
for (var i = 0; i < ap.length; i++) {
if (ap[i] && esa[i] && d[i] && !isNaN(ap[i]) && !isNaN(esa[i]) && !isNaN(d[i])) {
v = (ap[i] - esa[i]) / (0.015 * d[i])
arrCI.push(v)
} else {
arrCI.push(NaN)
}
}
if (arrCI.length == 0) {
return false
}
return arrCI
}
function CalcTCI (ci, n2) { // TCI:=EMA(CI,N2);
if (ci.length <= n2) {
return false
}
return TA.EMA(ci, n2)
}
এই শেষ ধাপে, আমরা আগে তৈরি করা চাকাটির SMA ফাংশন ব্যবহার করা হয়।
function CalcWT2 (wt1) { // WT2:SMA(WT1,4,1);
if (wt1.length <= 4) {
return false
}
return SMA(wt1, 4, 1) // The SMA indicator for wt1 is calculated by using our own implementation of the SMA function.
}
ট্রেডিং সিগন্যালের ট্রান্সপ্লেট খুবই সহজ।
AA:=CROSS(WT1,WT2);
BB:=CROSSDOWN(WT1,WT2);
REF(AA,1),BPK;
REF(BB,1),SPK;
মাইল্যাঙ্গুয়েজের এই কোডগুলি পড়ার পরে, আমরা দেখতে পাচ্ছি যে ডাব্লুটি 1 এবং ডাব্লুটি 2 এর গোল্ডেন ক্রস এবং বেয়ারিশ ক্রসওভার খোলার শর্ত হিসাবে ব্যবহৃত হয়। এটি লক্ষ করা উচিত যে পূর্ববর্তী ক্রস সংকেত ব্যবহার করা হয়। সরাসরি মাইল্যাঙ্গুয়েজ কৌশল ব্যাকটেস্ট ব্যবহার করে, আমরা পর্যবেক্ষণ করি যেঃ
মাইল্যাঙ্গুয়েজ কৌশলটির প্রকৃত অপারেশন পর্যবেক্ষণ থেকে দেখা যায় যে যখন একটি সংকেত খোলার অবস্থানে সনাক্ত করা হয়, তখন এটি আসলে এটি সনাক্ত করতে হয় যে খোলার বিন্দুতে 2 টি BAR এগিয়ে গণনা করা হচ্ছে কিনা তা একটি গোল্ডেন ক্রস। উপরের চিত্রটি স্পষ্টভাবে দেখায় যেঃ
সিগন্যাল সনাক্তকরণ অংশের ভরাট কোড লিখতে পারেনঃ
if ((_State == IDLE || _State == SHORT) && wt1[wt1.length - 4] < wt2[wt2.length - 4] && wt1[wt1.length - 3] > wt2[wt2.length - 3]) {
if (_State == IDLE) {
_State = OPENLONG
Log("OPENLONG") // test
}
if (_State == SHORT) {
_State = COVERSHORT
Log("COVERSHORT") // test
}
isOK = false
}
if ((_State == IDLE || _State == LONG) && wt1[wt1.length - 4] > wt2[wt2.length - 4] && wt1[wt1.length - 3] < wt2[wt2.length - 3]) {
if (_State == IDLE) {
_State = OPENSHORT
Log("OPENSHORT") // test
}
if (_State == LONG) {
_State = COVERLONG
Log("COVERLONG") // test
}
isOK = false
}
এখানে আপনি ভাবতে পারেন যে কেন MyLanguage এর SPK এবং BPK নির্দেশাবলী উপরের কোড দিয়ে বাস্তবায়ন করা যেতে পারে।
ব্যাকটেস্ট কনফিগারেশনঃ
মাইল্যাঙ্গুয়েজে ব্যাকটেস্টঃ
জাভাস্ক্রিপ্ট সংস্করণে ব্যাকটেস্টঃ
OnTick ফাংশনের শুরুতে থাকা কোডটি ব্যাকটেস্টিংকে দ্রুততর করতে ব্যবহৃত হয়। এটি বার মডেলের উপর ভিত্তি করে কৌশলটি চালানোর জন্য ব্যবহৃত হয়। যদি আপনি আগ্রহী হন তবে আপনি এটি বিশদভাবে বিশ্লেষণ করতে পারেন।
function OnTick(){
// The ticker processing part of the driving strategy.
var records = _C(exchange.GetRecords)
if (records[records.length - 1].Time == preTime) {
if (isOK) {
Sleep(500)
return
}
} else {
preTime = records[records.length - 1].Time
}
...
..
.
শিক্ষার সম্পূর্ণ কৌশল কোডঃhttps://www.fmz.com/strategy/174457