Скрипт в руки — деньги в карман.
Инструкция:
1. Бери «Скрипт».
2. Пиши «Тикер» из фондовой секции ММВБ.
3. Жми «График».
Вуаля… ваш брокерский счет наливается прибылью.
Чем жирнее цена, тем жирнее уровень.
Пользуйся и твоя эквити будет гладкая и больше чем вчера.
ПС: График влево.
Данные ММВБ с задержкой 15 минут.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<form name="search">
<input type="text" name="key" placeholder="Тикер" id="key"/>
<input type="button" name="buttonChart" value="График" />
</form>
<div id="printBlock"></div>
<canvas id="chart" width="4000" height="600"></canvas>
<script>
const keyBox = document.search.key;
const keyButton = document.search.buttonChart;
function DrawChart(prices,minPrice,maxPrice,maxVolume,ZZ,ZZDay){
var chart = document.getElementById("chart");
if (chart.getContext) {
var ctx = chart.getContext("2d");
ctx.lineWidth=1;
Point = 0;
for (let i = prices. <a name="cut"></a> length-1; i >= 0; i--) {
var K=600/(maxPrice-minPrice);
var pOpen = Math.trunc((prices[i].Open-minPrice)*K);
var pClose = Math.trunc((prices[i].Close-minPrice)*K);
var pMin = Math.trunc((prices[i].Low-minPrice)*K);
var pMax = Math.trunc((prices[i].High-minPrice)*K);
var dStart = 600-Math.max(pOpen,pClose);
var dFinish = 600-Math.min(pOpen,pClose);
var dMin = 600-pMin;
var dMax = 600-pMax;
var pVolume = Math.trunc((prices[i].Volume)/maxVolume*100);
var dVolume = 600-pVolume;
var AA = prices[i].Close - prices[i].Open;
//ctx.beginPath();
if (pOpen==pClose) {
ctx.fillStyle = "rgb(0,0,0)";
dFinish = dStart+1;
//console.log("-"+(Point*4)+" "+dStart+" "+dFinish + " "+AA+" "+pOpen+" "+pClose+" "+K);
}
else {
if (prices[i].Open>prices[i].Close) {
ctx.fillStyle = "rgb(200,0,0)";
}
else{
ctx.fillStyle = "rgb(0,200,0)";
}
}
if (Point==0) {
ctx.fillRect(Point, dStart, 40, 1);
ctx.textBaseline = "bottom";
ctx.font = "bold 8px Arial";
ctx.fillText(prices[i].Close, Point, dStart-2);
Point = Point+11;
}
//console.log(""+(Point*4)+" "+dStart+" "+dFinish + " "+AA+" "+pOpen+" "+pClose+" "+K);
ctx.fillRect(Point*4, dStart, 3, dFinish-dStart);
ctx.fillStyle = ctx.fillStyle.replace(")",",0.7)");
//console.log(""+prices[i].Volume+" "+maxVolume + " "+pVolume+" "+dVolume+" "+ctx.fillStyle);
ctx.fillRect(Point*4, dVolume, 3, 600-dVolume);
ctx.fillStyle = "rgb(0,0,0)";
ctx.fillRect(Point*4+1, dMax, 1, dStart-dMax);
ctx.fillRect(Point*4+1, dFinish, 1, dMin-dFinish);
Point ++;
}
DrawZZ(ZZ,ctx,prices,maxPrice,minPrice);
ctx.lineWidth=2;
DrawZZ(ZZDay,ctx,prices,maxPrice,minPrice);
var priceLevel = [];
ctx.lineWidth=1;
ctx.strokeStyle = "rgb(0,0,200,0.3)";
DrawK(ZZ,ctx,prices,maxPrice,minPrice,1,3,priceLevel);
DrawK(ZZ,ctx,prices,maxPrice,minPrice,3,5,priceLevel);
DrawK(ZZ,ctx,prices,maxPrice,minPrice,1,5,priceLevel);
DrawK(ZZ,ctx,prices,maxPrice,minPrice,2,4,priceLevel);
DrawK(ZZ,ctx,prices,maxPrice,minPrice,4,6,priceLevel);
DrawK(ZZ,ctx,prices,maxPrice,minPrice,2,6,priceLevel);
ctx.lineWidth=2;
DrawK(ZZDay,ctx,prices,maxPrice,minPrice,1,3,priceLevel);
DrawK(ZZDay,ctx,prices,maxPrice,minPrice,3,5,priceLevel);
DrawK(ZZDay,ctx,prices,maxPrice,minPrice,1,5,priceLevel);
DrawK(ZZDay,ctx,prices,maxPrice,minPrice,2,4,priceLevel);
DrawK(ZZDay,ctx,prices,maxPrice,minPrice,4,6,priceLevel);
DrawK(ZZDay,ctx,prices,maxPrice,minPrice,2,6,priceLevel);
priceLevel.sort(function(a,b){
if (a.Price<b.Price) return -1; else if (a.Price>b.Price) return 1; else return 0;
});
priceLevelGroup = [];
maxVolume = 0;
for (let i = 0; i < priceLevel.length; i++) {
console.log(""+priceLevel[i].Price+" "+priceLevel[i].Volume);
if (i==0) {
priceLevelGroup[0] = {Price:priceLevel[i].Price,Volume:priceLevel[i].Volume};
}
else{
if (priceLevel[i].Price/priceLevelGroup[priceLevelGroup.length-1].Price-1<0.003) {
priceLevelGroup[priceLevelGroup.length-1].Price =
(priceLevel[i].Volume*priceLevel[i].Price
+priceLevelGroup[priceLevelGroup.length-1].Volume*priceLevelGroup[priceLevelGroup.length-1].Price)
/(priceLevel[i].Volume+priceLevelGroup[priceLevelGroup.length-1].Volume);
priceLevelGroup[priceLevelGroup.length-1].Volume = priceLevelGroup[priceLevelGroup.length-1].Volume+priceLevel[i].Volume;
}
else{
priceLevelGroup[priceLevelGroup.length] = {Price:priceLevel[i].Price,Volume:priceLevel[i].Volume};
}
};
if (priceLevelGroup[priceLevelGroup.length-1].Volume>maxVolume){
maxVolume = priceLevelGroup[priceLevelGroup.length-1].Volume;
}
}
for (let i = 0; i < priceLevelGroup.length; i++) {
pOpen = Math.trunc((priceLevelGroup[i].Price-minPrice)*K);
dStart = 600-pOpen;
ctx.fillRect(0, dStart, 40, 1);
ctx.textBaseline = "bottom";
ctx.font = ""+(Math.trunc(priceLevelGroup[i].Volume/maxVolume*12)+6)+"px Arial";
console.log("g "+maxVolume+" "+priceLevelGroup[i].Volume+" "+ctx.font+" "+(Math.trunc(priceLevelGroup[i].Volume/maxVolume*12)+6));
//console.log("g "+priceLevelGroup[i].Price+" "+priceLevelGroup[i].Volume+" "+ctx.font+" "+(Math.trunc(priceLevelGroup[i].Volume/maxVolume*12)+6));
percent = Math.trunc((prices[prices.length-1].Close - priceLevelGroup[i].Price)/prices[prices.length-1].Close*10000)/100;
if (percent<0) {percent=-percent;ctx.fillStyle = "rgb(100,150,100)";}
else {ctx.fillStyle = "rgb(150,100,100)"};
ctx.fillText(""+Math.trunc(priceLevelGroup[i].Price*100)/100+" ("+percent+"%)", 0, dStart-1);
}
}
}
function DrawZZ(ZZ,ctx,prices,maxPrice,minPrice){
ctx.fillStyle = "rgb(0,0,0,0.7)";
ctx.beginPath();
for (let i = 0; i < ZZ.length; i++) {
Point = (prices.length - ZZ[i].Point+10)*4+1;
var K=600/(maxPrice-minPrice);
pPrice = Math.trunc((ZZ[i].price-minPrice)*K);
dStart = 600-pPrice;
//console.log(""+ZZ[i].price+" "+dStart+ " "+ZZ[i].Point+" "+ZZ[i].T);
if (i==0) {
ctx.moveTo(Point,dStart);
} else {
ctx.lineTo(Point,dStart);
}
}
ctx.stroke();
}
function DrawK(ZZ,ctx,prices,maxPrice,minPrice,p1,p2,priceLevel){
if (ZZ.length-p1<0 || ZZ.length-p2<0) {return};
var K=600/(maxPrice-minPrice);
first = ZZ.length - p1;
second = ZZ.length - p2;
//console.log(""+first+" "+second+" "+ZZ.length);
fPoint = (prices.length-ZZ[first].Point+10)*4+1;
sPoint = (prices.length-ZZ[second].Point+10)*4+1;
ePrice=ZZ[second].price+(prices.length-ZZ[second].Point)*(ZZ[first].price-ZZ[second].price)/(ZZ[first].Point-ZZ[second].Point)
priceLevel[priceLevel.length] = {Price:ePrice,Volume:(ZZ[second].Volume+ZZ[first].Volume)};
priceLevel[priceLevel.length] = {Price:ZZ[first].price,Volume:(ZZ[first].Volume)};
priceLevel[priceLevel.length] = {Price:ZZ[second].price,Volume:(ZZ[second].Volume)};
//console.log(""+ZZ[first].Point+" "+ZZ[second].Point+" "+" "+prices.length+" "+ZZ[first].price+" "+ZZ[second].price+" "+ePrice);
fPrice = Math.trunc((ZZ[first].price-minPrice)*K);
sPrice = Math.trunc((ZZ[second].price-minPrice)*K);
ePrice = Math.trunc((ePrice-minPrice)*K);
dStart = 600-sPrice;
dFinish = 600-ePrice;
//console.log(""+first+" "+second+" "+fPrice+" "+sPrice+" "+ePrice);
//ctx.fillStyle = "rgb(0,0,255,0.7)";
//console.log(""+ctx.fillStyle);
ctx.beginPath();
ctx.moveTo(sPoint,dStart);
ctx.lineTo(40,dFinish);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(sPoint,dStart);
ctx.lineTo(40,dStart);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(fPoint,600-fPrice);
ctx.lineTo(40,600-fPrice);
ctx.stroke();
}
function FillArray (data){
var prices = [];
var pricesDay = [];
var ZZ = [];
var ZZDay = [];
var minPrice = 9999999;
var maxPrice = 0;
var maxVolume = 0;
let md = data['candles']['data'];
for (let i = 0; i < md.length; i++) {
var cl = prices.length;
prices[cl] = [];
prices[cl] = {Period:md[i][6], Open:md[i][0], Close:md[i][1],Low:md[i][3], High:md[i][2], Volume:md[i][5], Period:md[i][6]}
if (minPrice>prices[cl].Low) {
minPrice = prices[cl].Low;
}
if (maxPrice<prices[cl].High) {
maxPrice = prices[cl].High;
}
if (maxVolume<prices[cl].Volume) {
maxVolume = prices[cl].Volume;
}
var cDay = prices[cl].Period;
cDay = cDay.substring(0,10);
PosDay=pricesDay.findIndex(item => item.Period == cDay);
if (PosDay==-1) {PosDay=pricesDay.length; pricesDay[PosDay]={Period:cDay,High:prices[cl].High,Low:prices[cl].Low,PeriodHi:i,PeriodLow:i,Volume:prices[cl].Volume}}
if (pricesDay[PosDay].High<prices[cl].High) {pricesDay[PosDay].High=prices[cl].High;pricesDay[PosDay].PeriodHi=cl;}
if (pricesDay[PosDay].Low>prices[cl].Low) {pricesDay[PosDay].Low=prices[cl].Low;pricesDay[PosDay].PeriodLow=cl;}
pricesDay[PosDay].Volume = pricesDay[PosDay].Volume+prices[cl].Volume;
if (cl>1) {
if (ZZ.length == 0) {
ZZ[0] = {price:(prices[cl-2].Open>prices[cl].Close ? prices[cl-2].High:prices[cl-2].Low),
Point:cl-2,
T:(prices[cl-2].Open>prices[cl].Close ? -1:1),
Volume:prices[cl-2].Volume}
//console.log("f "+ZZ[ZZ.length-1].price+" "+" "+ZZ[ZZ.length-1].Point+" "+ZZ[ZZ.length-1].T);
} else {
if (ZZ[ZZ.length-1].T == 1) {
//console.log("up "+ZZ[ZZ.length-1].price+" "+" "+ZZ[ZZ.length-1].Point+" "+ZZ[ZZ.length-1].T);
if (prices[cl-2].High<prices[cl].High || prices[cl-1].High<prices[cl].High || prices[cl-2].Low<prices[cl].Low || prices[cl-1].Low<prices[cl].Low) {}
else {
ZZ[ZZ.length]={price:(Math.max(prices[cl-2].High,prices[cl-1].High)),
Point:(prices[cl-2].High>prices[cl-1].High ? cl-2:cl-1),
T:-1,
Volume:(prices[cl-2].High>prices[cl-1].High ? prices[cl-2].Volume:prices[cl-1].Volume)}
//console.log("up "+ZZ[ZZ.length-1].price+" "+" "+ZZ[ZZ.length-1].Point+" "+ZZ[ZZ.length-1].T);
}
}
else {
if (ZZ[ZZ.length-1].T == -1) {
if (prices[cl-2].Low>prices[cl].Low || prices[cl-1].Low>prices[cl].Low || prices[cl-2].High>prices[cl].High || prices[cl-1].High>prices[cl].High) {}
else {
ZZ[ZZ.length]={price:(Math.min(prices[cl-2].Low,prices[cl-1].Low)),
Point:(prices[cl-2].Low<prices[cl-1].Low ? cl-2:cl-1),
T:1,
Volume:(prices[cl-2].Low<prices[cl-1].Low ? prices[cl-2].Volume:prices[cl-1].Volume)}
//console.log("dw "+ZZ[ZZ.length-1].price+" "+" "+ZZ[ZZ.length-1].Point+" "+ZZ[ZZ.length-1].T);
}
}
}
}
}
}
for (let cl = 0; cl < pricesDay.length; cl++) {
//console.log(""+pricesDay[cl].Period+" "+pricesDay[cl].High+" "+pricesDay[cl].Low+" "+pricesDay[cl].Volume+" "+pricesDay[cl].PeriodHi+" "+pricesDay[cl].PeriodLow);
if (cl>1) {
if (ZZDay.length == 0) {
ZZDay[0] = {price:(pricesDay[cl-2].Open>pricesDay[cl].Close ? pricesDay[cl-2].High:pricesDay[cl-2].Low),
Point:(pricesDay[cl-2].Open>pricesDay[cl].Close ? pricesDay[cl-2].PeriodHi:pricesDay[cl-2].PeriodLow),
T:(pricesDay[cl-2].Open>pricesDay[cl].Close ? -1:1),
Volume:prices[cl-2].Volume}
//console.log("f "+ZZDay[ZZDay.length-1].price+" "+" "+ZZDay[ZZDay.length-1].Point+" "+ZZDay[ZZDay.length-1].T);
} else {
if (ZZDay[ZZDay.length-1].T == 1) {
//console.log("up "+ZZDay[ZZDay.length-1].price+" "+" "+ZZDay[ZZDay.length-1].Point+" "+ZZDay[ZZDay.length-1].T);
if (pricesDay[cl-2].High<pricesDay[cl].High || pricesDay[cl-1].High<pricesDay[cl].High || pricesDay[cl-2].Low<pricesDay[cl].Low || pricesDay[cl-1].Low<pricesDay[cl].Low) {}
else {
ZZDay[ZZDay.length]={price:(Math.max(pricesDay[cl-2].High,pricesDay[cl-1].High)),
Point:(pricesDay[cl-2].High>pricesDay[cl-1].High ? pricesDay[cl-2].PeriodHi:pricesDay[cl-1].PeriodHi),
T:-1,
Volume:(pricesDay[cl-2].High>pricesDay[cl-1].High ? pricesDay[cl-2].Volume:pricesDay[cl-1].Volume)}
//console.log("up "+ZZDay[ZZDay.length-1].price+" "+" "+ZZDay[ZZDay.length-1].Point+" "+ZZDay[ZZDay.length-1].T);
}
}
else {
if (ZZDay[ZZDay.length-1].T == -1) {
if (pricesDay[cl-2].Low>pricesDay[cl].Low || pricesDay[cl-1].Low>pricesDay[cl].Low || pricesDay[cl-2].High>pricesDay[cl].High || pricesDay[cl-1].High>pricesDay[cl].High) {}
else {
ZZDay[ZZDay.length]={price:(Math.min(pricesDay[cl-2].Low,pricesDay[cl-1].Low)),
Point:(pricesDay[cl-2].Low<pricesDay[cl-1].Low ? pricesDay[cl-2].PeriodLow:pricesDay[cl-1].PeriodLow),
T:1,
Volume:(pricesDay[cl-2].Low<pricesDay[cl-1].Low ? pricesDay[cl-2].Volume:pricesDay[cl-1].Volume)}
//console.log("dw "+ZZDay[ZZDay.length-1].price+" "+" "+ZZDay[ZZDay.length-1].Point+" "+ZZDay[ZZDay.length-1].T);
}
}
}
}
}
}
DrawChart(prices,minPrice,maxPrice,maxVolume,ZZ,ZZDay);
return prices;
}
function strRight(n,str){
return str.substring(str.length-n,str.length);
}
// обработчик изменения текста
function onchange(e){
// получаем элемент printBlock
const printBlock = document.getElementById("printBlock");
const tiker = document.getElementById("key").value;
// получаем новое значение
const val = tiker;
// установка значения
printBlock.textContent = printBlock.textContent+" "+tiker;
var URL = "https://iss.moex.com/iss/engines/stock/markets/shares/securities/<TIKER>/candles.json?from=<DateFrom>&interval=60";
URL = URL.replace("<TIKER>", val);
var now = new Date();
now.setDate(now.getDate() - 45);
console.log(now);
var Month=now.getMonth()+1;
var year=now.getFullYear();
//if (Month<0) {Month=12+Month+1; year--;};
var startdata = (year).toString()+"-"+strRight(2,"0"+Month.toString())+"-"+strRight(2,"0"+now.getDate().toString());
URL = URL.replace("<DateFrom>", startdata);
console.log(URL);
fetch(URL)
.then(function (response) {
return response.json();
})
.then(function (data) {
FillArray(data);
})
}
//keyBox.addEventListener("change", onchange);
keyButton.addEventListener("click", onchange);
</script>
</body>
</html>