Не могу разобраться с json
Цитата: Евгений от 25.01.2023, 13:49Всем доброго времени!
Пытаюсь что-то сделать на c#...
Есть код, который по API берет информацию: символ/монета и его цена, делает расчёт и редактирует xml файл.
[spoiler title="Код"]using System; using System.Linq; using System.Net; using System.Collections.Generic; using System.Web.Script.Serialization; using System.Windows.Forms; using System.Xml.Linq; using System.IO; namespace Test { public partial class Form1 : Form { public Form1() { InitializeComponent(); } string url_fut = "https://www.binance.com/fapi/v1/ticker/price"; string url_exchangeInfo_fut = "https://www.binance.com/fapi/v1/exchangeInfo"; void calculate_Click_1(object sender, EventArgs e) { using (WebClient client = new WebClient()) { string json = client.DownloadString(url_fut); var serializer = new JavaScriptSerializer(); int count_fut = 0; List<PriceData> prices = serializer.Deserialize<List<PriceData>>(json); foreach (PriceData price in prices) { #region Переменные string first_WorkAmount = (Convert.ToDouble(value_1.Text) / price.price).ToString(); string fileName_fut = $"BINAD.CCUR_FUT.{price.symbol}_Settings_55555.xml"; #endregion if (File.Exists(fileName_fut)) { XDocument doc = XDocument.Load(fileName_fut); void Descend(string x, string y) { doc.Descendants(x).First().SetAttributeValue("Value", y); } Descend("First_WorkAmount", first_WorkAmount); doc.Save(fileName_fut); count_fut++; } else { continue; } } MessageBox.Show("Изменён", Text, MessageBoxButtons.OK); } } } class PriceData { public string symbol { get; set; } public double price { get; set; } } }[/spoiler]
Всё работает как надо, но значение переменной first_WorkAmount слишком сильно дробится. У каждого символа/монеты есть свой "stepSize", который можно узнать по API в переменной url_exchangeInfo_fut. Так вот мне надо как-то округлить значение, которое получается в переменной first_WorkAmount, для каждого символа в соответствии с его размером "stepSize".
Совсем не пойму как это сделать...
Всем доброго времени!
Пытаюсь что-то сделать на c#...
Есть код, который по API берет информацию: символ/монета и его цена, делает расчёт и редактирует xml файл.
using System;
using System.Linq;
using System.Net;
using System.Collections.Generic;
using System.Web.Script.Serialization;
using System.Windows.Forms;
using System.Xml.Linq;
using System.IO;
namespace Test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
string url_fut = "https://www.binance.com/fapi/v1/ticker/price";
string url_exchangeInfo_fut = "https://www.binance.com/fapi/v1/exchangeInfo";
void calculate_Click_1(object sender, EventArgs e)
{
using (WebClient client = new WebClient())
{
string json = client.DownloadString(url_fut);
var serializer = new JavaScriptSerializer();
int count_fut = 0;
List<PriceData> prices = serializer.Deserialize<List<PriceData>>(json);
foreach (PriceData price in prices)
{
#region Переменные
string first_WorkAmount = (Convert.ToDouble(value_1.Text) / price.price).ToString();
string fileName_fut = $"BINAD.CCUR_FUT.{price.symbol}_Settings_55555.xml";
#endregion
if (File.Exists(fileName_fut))
{
XDocument doc = XDocument.Load(fileName_fut);
void Descend(string x, string y)
{
doc.Descendants(x).First().SetAttributeValue("Value", y);
}
Descend("First_WorkAmount", first_WorkAmount);
doc.Save(fileName_fut);
count_fut++;
}
else
{
continue;
}
}
MessageBox.Show("Изменён", Text, MessageBoxButtons.OK);
}
}
}
class PriceData
{
public string symbol { get; set; }
public double price { get; set; }
}
}
Всё работает как надо, но значение переменной first_WorkAmount слишком сильно дробится. У каждого символа/монеты есть свой "stepSize", который можно узнать по API в переменной url_exchangeInfo_fut. Так вот мне надо как-то округлить значение, которое получается в переменной first_WorkAmount, для каждого символа в соответствии с его размером "stepSize".
Совсем не пойму как это сделать...
Цитата: Никита от 25.01.2023, 16:02Евгений, привет.
Если я правильно понял, имеешь на выходе число 127.118288191, а нужно его сократить до 127.11 напимер?
Если так, то можно
[spoiler title="Пример"]double num = 127.11828811;double cutedDouble = double.Parse(num.ToString("0.00"));MessageBox.Show(cutedDouble.ToString());[/spoiler]
Евгений, привет.
Если я правильно понял, имеешь на выходе число 127.118288191, а нужно его сократить до 127.11 напимер?
Если так, то можно
Скопированоdouble num = 127.11828811;Скопированоdouble cutedDouble = double.Parse(num.ToString("0.00"));СкопированоMessageBox.Show(cutedDouble.ToString());
Цитата: Евгений от 25.01.2023, 16:57Цитата: Никита от 25.01.2023, 16:02Евгений, привет.
Если я правильно понял, имеешь на выходе число 127.118288191, а нужно его сократить до 127.11 напимер?
Если так, то можно
[spoiler title="Пример"]double num = 127.11828811;double cutedDouble = double.Parse(num.ToString("0.00"));MessageBox.Show(cutedDouble.ToString());[/spoiler]
Да, сократить надо так, только в соответствии со stepSize, получается монет например 20 штук, у какой-то монеты stepSize 0.1 тогда тогда для неё будет в итоге 127.1, а у какой-то монеты stepSize 0.001 и тогда для неё получится соответственно 127.118. Этот stepSize есть по апи, для каждой монеты stepSize свой и вот как их сопоставить вообще не пойму...
Цитата: Никита от 25.01.2023, 16:02Евгений, привет.
Если я правильно понял, имеешь на выходе число 127.118288191, а нужно его сократить до 127.11 напимер?
Если так, то можно
ПримерСкопированоdouble num = 127.11828811;Скопированоdouble cutedDouble = double.Parse(num.ToString("0.00"));СкопированоMessageBox.Show(cutedDouble.ToString());
Да, сократить надо так, только в соответствии со stepSize, получается монет например 20 штук, у какой-то монеты stepSize 0.1 тогда тогда для неё будет в итоге 127.1, а у какой-то монеты stepSize 0.001 и тогда для неё получится соответственно 127.118. Этот stepSize есть по апи, для каждой монеты stepSize свой и вот как их сопоставить вообще не пойму...
Цитата: Adler от 25.01.2023, 17:04Самое первое, что пришло в голову, но достаточно тупое решение, делать как-то так
double cutedDouble = double.Parse(num.ToString(stepSize.ToString().Replace("1","0")));Хотя уверен есть и более правильный вариант.
Самое первое, что пришло в голову, но достаточно тупое решение, делать как-то так
double cutedDouble = double.Parse(num.ToString(stepSize.ToString().Replace("1","0")));
Хотя уверен есть и более правильный вариант.
Цитата: Евгений от 25.01.2023, 17:13Цитата: Adler от 25.01.2023, 17:04Самое первое, и вероятно, самое тупое, делать как-то так
double cutedDouble = double.Parse(num.ToString(stepSize.ToString().Replace("1","0")));double cutedDouble = double.Parse(num.ToString(stepSize.ToString().Replace("1","0")));double cutedDouble = double.Parse(num.ToString(stepSize.ToString().Replace("1","0")));Хотя уверен есть и более правильный вариант.
Я уверен в том, что stepSize должен присутствовать именно в расчётах вот тут
string first_WorkAmount = (Convert.ToDouble(value_1.Text) / price.price).ToString();
Цитата: Adler от 25.01.2023, 17:04Самое первое, и вероятно, самое тупое, делать как-то так
double cutedDouble = double.Parse(num.ToString(stepSize.ToString().Replace("1","0")));double cutedDouble = double.Parse(num.ToString(stepSize.ToString().Replace("1","0")));double cutedDouble = double.Parse(num.ToString(stepSize.ToString().Replace("1","0")));Хотя уверен есть и более правильный вариант.
Я уверен в том, что stepSize должен присутствовать именно в расчётах вот тут
string first_WorkAmount = (Convert.ToDouble(value_1.Text) / price.price).ToString();
Цитата: Никита от 25.01.2023, 17:35Евгений, если stepSize имеет именно тот формат, что ты написал, то должно работать.
string first_WorkAmount = ((double.Parse(value_1.Text) / price.price)).ToString(stepSize.Replace("1", "0"));
Евгений, если stepSize имеет именно тот формат, что ты написал, то должно работать.
string first_WorkAmount = ((double.Parse(value_1.Text) / price.price)).ToString(stepSize.Replace("1", "0"));
Цитата: Никита от 25.01.2023, 17:42Только если сам stepSize является числом, а не строкой, то перед этим преобразуй его в строку.
string strStepSize = stepSize.ToString(); string first_WorkAmount = ((double.Parse(value_1.Text) / price.price)).ToString(strStepSize.Replace("1", "0"));
Только если сам stepSize является числом, а не строкой, то перед этим преобразуй его в строку.
string strStepSize = stepSize.ToString();
string first_WorkAmount = ((double.Parse(value_1.Text) / price.price)).ToString(strStepSize.Replace("1", "0"));
Цитата: Евгений от 25.01.2023, 18:38Цитата: Никита от 25.01.2023, 17:42Только если сам stepSize является числом, а не строкой, то перед этим преобразуй его в строку.
string strStepSize = stepSize.ToString();string first_WorkAmount = ((double.Parse(value_1.Text) / price.price)).ToString(strStepSize.Replace("1", "0"));string strStepSize = stepSize.ToString(); string first_WorkAmount = ((double.Parse(value_1.Text) / price.price)).ToString(strStepSize.Replace("1", "0"));string strStepSize = stepSize.ToString(); string first_WorkAmount = ((double.Parse(value_1.Text) / price.price)).ToString(strStepSize.Replace("1", "0"));@adler, @dvgm, парни, я не на столько умный как вам кажется ))) что мне надо ещё сделать с этим stepSize. Сначала так же загрузить строку
string json_exchange = client.DownloadString(url_exchangeInfo_fut);Далее десериализовать её
var serializer_exchange = new JavaScriptSerializer(); List<Filter> exchangeInfo = serializer_exchange.Deserialize<List<Filter>>(json_exchange);Добавить класс
public class Filter { public string stepSize { get; set; } }И потом только попробовать ваш вариант
string first_WorkAmount = ((double.Parse(value_1.Text) / price.price)).ToString(stepSize.Replace("1", "0"));Не судите строго, я совсем новичок, но хочется как-то разобраться )
Цитата: Никита от 25.01.2023, 17:42Только если сам stepSize является числом, а не строкой, то перед этим преобразуй его в строку.
string strStepSize = stepSize.ToString();string first_WorkAmount = ((double.Parse(value_1.Text) / price.price)).ToString(strStepSize.Replace("1", "0"));string strStepSize = stepSize.ToString(); string first_WorkAmount = ((double.Parse(value_1.Text) / price.price)).ToString(strStepSize.Replace("1", "0"));string strStepSize = stepSize.ToString(); string first_WorkAmount = ((double.Parse(value_1.Text) / price.price)).ToString(strStepSize.Replace("1", "0"));
@adler, @dvgm, парни, я не на столько умный как вам кажется ))) что мне надо ещё сделать с этим stepSize. Сначала так же загрузить строку
string json_exchange = client.DownloadString(url_exchangeInfo_fut);
Далее десериализовать её
var serializer_exchange = new JavaScriptSerializer(); List<Filter> exchangeInfo = serializer_exchange.Deserialize<List<Filter>>(json_exchange);
Добавить класс
public class Filter
{
public string stepSize { get; set; }
}
И потом только попробовать ваш вариант
string first_WorkAmount = ((double.Parse(value_1.Text) / price.price)).ToString(stepSize.Replace("1", "0"));
Не судите строго, я совсем новичок, но хочется как-то разобраться )
Цитата: Dapofig от 25.01.2023, 19:57Всем привет! Вы уверены, что нужно округлять именно по
stepSize?
Самый первый элемент ответа API в моём случае выдал0.02931дляIOTXUSDT, но егоstepSize = 1. Причём, у некоторых символов, он отличается в зависимости отfilterType(LOT_SIZE, MARKET_LOT_SIZE, возможно, другие).
Всем привет! Вы уверены, что нужно округлять именно по СкопированоstepSize?
Самый первый элемент ответа API в моём случае выдал Скопировано0.02931 для СкопированоIOTXUSDT, но его СкопированоstepSize = 1. Причём, у некоторых символов, он отличается в зависимости от СкопированоfilterType (LOT_SIZE, MARKET_LOT_SIZE, возможно, другие).
Цитата: Евгений от 25.01.2023, 21:12Цитата: Dapofig от 25.01.2023, 19:57Всем привет! Вы уверены, что нужно округлять именно по
stepSize?
Самый первый элемент ответа API в моём случае выдал0.02931дляIOTXUSDT, но егоstepSize = 1. Причём, у некоторых символов, он отличается в зависимости отfilterType(LOT_SIZE, MARKET_LOT_SIZE, возможно, другие).[spoiler title=""]<img class="lazyload" src="data:;base64," alt="" width="216" height="100" data-orig-src="https://i.imgur.com/YIov5lJ.png" />
<img class="lazyload" src="data:;base64," alt="" width="324" height="650" data-orig-src="https://i.imgur.com/vMiemj2.png" />
[/spoiler]IOTX
Всё верно, нужно именно по фильтру (LOT_SIZE, взять значение stepSize = 1). В картинке показал наглядно, видите там написано Шаг=1, цена монеты на это ни как не влияет, в цене может быть много цифр после запятой...
Цитата: Dapofig от 25.01.2023, 19:57Всем привет! Вы уверены, что нужно округлять именно по
СкопированоstepSize?
Самый первый элемент ответа API в моём случае выдалСкопировано0.02931дляСкопированоIOTXUSDT, но егоСкопированоstepSize = 1. Причём, у некоторых символов, он отличается в зависимости отСкопированоfilterType(LOT_SIZE, MARKET_LOT_SIZE, возможно, другие).Спойлер<img class="lazyload" src="data:;base64," alt="" width="216" height="100" data-orig-src="https://i.imgur.com/YIov5lJ.png" style="color: #25d39d !important" />
<img class="lazyload" src="data:;base64," alt="" width="324" height="650" data-orig-src="https://i.imgur.com/vMiemj2.png" style="color: #25d39d !important" />
IOTX
Всё верно, нужно именно по фильтру (LOT_SIZE, взять значение stepSize = 1). В картинке показал наглядно, видите там написано Шаг=1, цена монеты на это ни как не влияет, в цене может быть много цифр после запятой...
Цитата: Никита от 25.01.2023, 21:28Евгений, я попробую ещё раз уточнить)
first_WorkAmount = какое-то число разделить на какое-то число.
Например (388,11 / 33) = 11.7609090909
Соответсвенно тебе нужно сделать, чтобы first_WorkAmount был равен не 11.7609090909, а например 11.760 (кол-во чисел после точки прописывается в том самом stepSize)
Я верно понял?
Если да, то сначала запиши вstring [simple_tooltip content='Создать новую строку в которой будет прописан твой stepSize']strStepSize[/simple_tooltip] = [simple_tooltip content='Это и есть твой stepSize']stepSize[/simple_tooltip].ToString();
После чего уже расчитай свой first_WorkAmount такstring first_WorkAmount = ((double.Parse(value_1.Text) / price.price)).ToString([simple_tooltip content='Это та самая строка на основе stepSize, которую создали выше']strStepSize[/simple_tooltip].Replace("1", "0"));
Евгений, я попробую ещё раз уточнить)
first_WorkAmount = какое-то число разделить на какое-то число.
Например (388,11 / 33) = 11.7609090909
Соответсвенно тебе нужно сделать, чтобы first_WorkAmount был равен не 11.7609090909, а например 11.760 (кол-во чисел после точки прописывается в том самом stepSize)
Я верно понял?
Если да, то сначала запиши в Скопированоstring strStepSize = stepSize.ToString();
После чего уже расчитай свой first_WorkAmount так Скопированоstring first_WorkAmount = ((double.Parse(value_1.Text) / price.price)).ToString(strStepSize.Replace("1", "0"));
Цитата: Евгений от 25.01.2023, 21:35Цитата: Никита от 25.01.2023, 21:28Евгений, я попробую ещё раз уточнить)
first_WorkAmount = какое-то число разделить на какое-то число.
Например (388,11 / 33) = 11.7609090909
Соответсвенно тебе нужно сделать, чтобы first_WorkAmount был равен не 11.7609090909, а например 11.760 (кол-во чисел после точки прописывается в том самом stepSize)
Я верно понял?
Если да, то сначала запиши вstring [simple_tooltip content='Создать новую строку в которой будет прописан твой stepSize']strStepSize[/simple_tooltip] = [simple_tooltip content='Это и есть твой stepSize']stepSize[/simple_tooltip].ToString();
После чего уже расчитай свой first_WorkAmount такstring first_WorkAmount = ((double.Parse(value_1.Text) / price.price)).ToString([simple_tooltip content='Это та самая строка на основе stepSize, которую создали выше']strStepSize[/simple_tooltip].Replace("1", "0"));
Всё верно first_WorkAmount = число которое ввели в textBox / на цену монеты и округлить результат до stepSize. Цену монеты получаю по первому апи. С этим проблем нет, всё ок работает. Но как мне добраться до stepSize. Там эти все зависимости в строке, которую по апи получаю...
[spoiler title=" Структура того самого JSON"]{ "exchangeFilters": [], "rateLimits": [ { "interval": "MINUTE", "intervalNum": 1, "limit": 2400, "rateLimitType": "REQUEST_WEIGHT" }, { "interval": "MINUTE", "intervalNum": 1, "limit": 1200, "rateLimitType": "ORDERS" } ], "serverTime": 1565613908500, // Ignore please. If you want to check current server time, please check via "GET /fapi/v1/time" "assets": [ // assets information { "asset": "BUSD", "marginAvailable": true, // whether the asset can be used as margin in Multi-Assets mode "autoAssetExchange": 0 // auto-exchange threshold in Multi-Assets margin mode }, { "asset": "USDT", "marginAvailable": true, "autoAssetExchange": 0 }, { "asset": "BNB", "marginAvailable": false, "autoAssetExchange": null } ], "symbols": [ { "symbol": "BLZUSDT", "pair": "BLZUSDT", "contractType": "PERPETUAL", "deliveryDate": 4133404800000, "onboardDate": 1598252400000, "status": "TRADING", "maintMarginPercent": "2.5000", // ignore "requiredMarginPercent": "5.0000", // ignore "baseAsset": "BLZ", "quoteAsset": "USDT", "marginAsset": "USDT", "pricePrecision": 5, // please do not use it as tickSize "quantityPrecision": 0, // please do not use it as stepSize "baseAssetPrecision": 8, "quotePrecision": 8, "underlyingType": "COIN", "underlyingSubType": ["STORAGE"], "settlePlan": 0, "triggerProtect": "0.15", // threshold for algo order with "priceProtect" "filters": [ { "filterType": "PRICE_FILTER", "maxPrice": "300", "minPrice": "0.0001", "tickSize": "0.0001" }, { "filterType": "LOT_SIZE", "maxQty": "10000000", "minQty": "1", "stepSize": "1" }, { "filterType": "MARKET_LOT_SIZE", "maxQty": "590119", "minQty": "1", "stepSize": "1" }, { "filterType": "MAX_NUM_ORDERS", "limit": 200 }, { "filterType": "MAX_NUM_ALGO_ORDERS", "limit": 100 }, { "filterType": "MIN_NOTIONAL", "notional": "1", }, { "filterType": "PERCENT_PRICE", "multiplierUp": "1.1500", "multiplierDown": "0.8500", "multiplierDecimal": 4 } ], "OrderType": [ "LIMIT", "MARKET", "STOP", "STOP_MARKET", "TAKE_PROFIT", "TAKE_PROFIT_MARKET", "TRAILING_STOP_MARKET" ], "timeInForce": [ "GTC", "IOC", "FOK", "GTX" ], "liquidationFee": "0.010000", // liquidation fee rate "marketTakeBound": "0.30", // the max price difference rate( from mark price) a market order can make } ], "timezone": "UTC" }[/spoiler]
Цитата: Никита от 25.01.2023, 21:28Евгений, я попробую ещё раз уточнить)
first_WorkAmount = какое-то число разделить на какое-то число.
Например (388,11 / 33) = 11.7609090909
Соответсвенно тебе нужно сделать, чтобы first_WorkAmount был равен не 11.7609090909, а например 11.760 (кол-во чисел после точки прописывается в том самом stepSize)
Я верно понял?
Если да, то сначала запиши вСкопированоstring strStepSize = stepSize.ToString();
После чего уже расчитай свой first_WorkAmount такСкопированоstring first_WorkAmount = ((double.Parse(value_1.Text) / price.price)).ToString(strStepSize.Replace("1", "0"));
Всё верно first_WorkAmount = число которое ввели в textBox / на цену монеты и округлить результат до stepSize. Цену монеты получаю по первому апи. С этим проблем нет, всё ок работает. Но как мне добраться до stepSize. Там эти все зависимости в строке, которую по апи получаю...
{
"exchangeFilters": [],
"rateLimits": [
{
"interval": "MINUTE",
"intervalNum": 1,
"limit": 2400,
"rateLimitType": "REQUEST_WEIGHT"
},
{
"interval": "MINUTE",
"intervalNum": 1,
"limit": 1200,
"rateLimitType": "ORDERS"
}
],
"serverTime": 1565613908500, // Ignore please. If you want to check current server time, please check via "GET /fapi/v1/time"
"assets": [ // assets information
{
"asset": "BUSD",
"marginAvailable": true, // whether the asset can be used as margin in Multi-Assets mode
"autoAssetExchange": 0 // auto-exchange threshold in Multi-Assets margin mode
},
{
"asset": "USDT",
"marginAvailable": true,
"autoAssetExchange": 0
},
{
"asset": "BNB",
"marginAvailable": false,
"autoAssetExchange": null
}
],
"symbols": [
{
"symbol": "BLZUSDT",
"pair": "BLZUSDT",
"contractType": "PERPETUAL",
"deliveryDate": 4133404800000,
"onboardDate": 1598252400000,
"status": "TRADING",
"maintMarginPercent": "2.5000", // ignore
"requiredMarginPercent": "5.0000", // ignore
"baseAsset": "BLZ",
"quoteAsset": "USDT",
"marginAsset": "USDT",
"pricePrecision": 5, // please do not use it as tickSize
"quantityPrecision": 0, // please do not use it as stepSize
"baseAssetPrecision": 8,
"quotePrecision": 8,
"underlyingType": "COIN",
"underlyingSubType": ["STORAGE"],
"settlePlan": 0,
"triggerProtect": "0.15", // threshold for algo order with "priceProtect"
"filters": [
{
"filterType": "PRICE_FILTER",
"maxPrice": "300",
"minPrice": "0.0001",
"tickSize": "0.0001"
},
{
"filterType": "LOT_SIZE",
"maxQty": "10000000",
"minQty": "1",
"stepSize": "1"
},
{
"filterType": "MARKET_LOT_SIZE",
"maxQty": "590119",
"minQty": "1",
"stepSize": "1"
},
{
"filterType": "MAX_NUM_ORDERS",
"limit": 200
},
{
"filterType": "MAX_NUM_ALGO_ORDERS",
"limit": 100
},
{
"filterType": "MIN_NOTIONAL",
"notional": "1",
},
{
"filterType": "PERCENT_PRICE",
"multiplierUp": "1.1500",
"multiplierDown": "0.8500",
"multiplierDecimal": 4
}
],
"OrderType": [
"LIMIT",
"MARKET",
"STOP",
"STOP_MARKET",
"TAKE_PROFIT",
"TAKE_PROFIT_MARKET",
"TRAILING_STOP_MARKET"
],
"timeInForce": [
"GTC",
"IOC",
"FOK",
"GTX"
],
"liquidationFee": "0.010000", // liquidation fee rate
"marketTakeBound": "0.30", // the max price difference rate( from mark price) a market order can make
}
],
"timezone": "UTC"
}
Цитата: Dapofig от 25.01.2023, 22:02Насколько я понимаю, сейчас вся сложность в получении
stepSizeпо API. Написал небольшое консольное приложение / пример, которое получает список всех символов,stepSizeи печатает пример округления для указанногоworkAmount.[spoiler title="Код"]
using System.Text.Json; using System.Text.Json.Serialization; const string FORMAT = "{0,-15} {1,-8} {2, -8} {3, -20}"; const string PRICE_URL = "https://www.binance.com/fapi/v1/ticker/price"; const string EXCHANGE_INFO_URL = "https://www.binance.com/fapi/v1/exchangeInfo"; const decimal WORK_AMOUNT = 5; Console.WriteLine(FORMAT, "Symbol", "Step", "Rounded", "Initial"); var exchangeModel = await Request<ExchangeModel>(EXCHANGE_INFO_URL); var priceModels = await Request<IEnumerable<PriceModel>>(PRICE_URL); foreach (var model in priceModels) { var step = exchangeModel.Symbols .First(x => x.Symbol == model.Symbol).Filters .First(x => x.FilterType == "LOT_SIZE").StepSize; var initial = WORK_AMOUNT / model.Price; var rounded = Round(initial, step); Console.WriteLine(FORMAT, model.Symbol, step, rounded, initial); } static decimal Round(decimal number, decimal step) { return Math.Floor(number / step) * step; } static async Task<T> Request<T>(string url) { using var client = new HttpClient(); var response = await client.GetAsync(url); response.EnsureSuccessStatusCode(); var json = await response.Content.ReadAsStringAsync(); return Deserialize<T>(json); } static T Deserialize<T>(string json) { var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, NumberHandling = JsonNumberHandling.AllowReadingFromString }; return JsonSerializer.Deserialize<T>(json, options)!; } record PriceModel(string Symbol, decimal Price); record ExchangeModel(IEnumerable<SymbolModel> Symbols); record SymbolModel(string Symbol, IEnumerable<FilterModel> Filters); record FilterModel(string FilterType, decimal StepSize);[/spoiler]
Насколько я понимаю, сейчас вся сложность в получении СкопированоstepSize по API. Написал небольшое консольное приложение / пример, которое получает список всех символов, СкопированоstepSize и печатает пример округления для указанного СкопированоworkAmount.
using System.Text.Json;
using System.Text.Json.Serialization;
const string FORMAT = "{0,-15} {1,-8} {2, -8} {3, -20}";
const string PRICE_URL = "https://www.binance.com/fapi/v1/ticker/price";
const string EXCHANGE_INFO_URL = "https://www.binance.com/fapi/v1/exchangeInfo";
const decimal WORK_AMOUNT = 5;
Console.WriteLine(FORMAT, "Symbol", "Step", "Rounded", "Initial");
var exchangeModel = await Request<ExchangeModel>(EXCHANGE_INFO_URL);
var priceModels = await Request<IEnumerable<PriceModel>>(PRICE_URL);
foreach (var model in priceModels)
{
var step = exchangeModel.Symbols
.First(x => x.Symbol == model.Symbol).Filters
.First(x => x.FilterType == "LOT_SIZE").StepSize;
var initial = WORK_AMOUNT / model.Price;
var rounded = Round(initial, step);
Console.WriteLine(FORMAT, model.Symbol, step, rounded, initial);
}
static decimal Round(decimal number, decimal step)
{
return Math.Floor(number / step) * step;
}
static async Task<T> Request<T>(string url)
{
using var client = new HttpClient();
var response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();
return Deserialize<T>(json);
}
static T Deserialize<T>(string json)
{
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
NumberHandling = JsonNumberHandling.AllowReadingFromString
};
return JsonSerializer.Deserialize<T>(json, options)!;
}
record PriceModel(string Symbol, decimal Price);
record ExchangeModel(IEnumerable<SymbolModel> Symbols);
record SymbolModel(string Symbol, IEnumerable<FilterModel> Filters);
record FilterModel(string FilterType, decimal StepSize);
Цитата: Евгений от 25.01.2023, 22:24Цитата: Dapofig от 25.01.2023, 22:02Насколько я понимаю, сейчас вся сложность в получении
stepSizeпо API. Написал небольшое консольное приложение / пример, которое получает список всех символов,stepSizeи печатает пример округления для указанногоworkAmount.[spoiler title="Код"]
using System.Text.Json;using System.Text.Json.Serialization;const string FORMAT = "{0,-15} {1,-8} {2, -8} {3, -20}";const string PRICE_URL = "https://www.binance.com/fapi/v1/ticker/price";const string EXCHANGE_INFO_URL = "https://www.binance.com/fapi/v1/exchangeInfo";const decimal WORK_AMOUNT = 5;Console.WriteLine(FORMAT, "Symbol", "Step", "Rounded", "Initial");var exchangeModel = await Request<ExchangeModel>(EXCHANGE_INFO_URL);var priceModels = await Request<IEnumerable<PriceModel>>(PRICE_URL);foreach (var model in priceModels){var step = exchangeModel.Symbols.First(x => x.Symbol == model.Symbol).Filters.First(x => x.FilterType == "LOT_SIZE").StepSize;var initial = WORK_AMOUNT / model.Price;var rounded = Round(initial, step);Console.WriteLine(FORMAT, model.Symbol, step, rounded, initial);}static decimal Round(decimal number, decimal step){return Math.Floor(number / step) * step;}static async Task<T> Request<T>(string url){using var client = new HttpClient();var response = await client.GetAsync(url);response.EnsureSuccessStatusCode();var json = await response.Content.ReadAsStringAsync();return Deserialize<T>(json);}static T Deserialize<T>(string json){var options = new JsonSerializerOptions{PropertyNamingPolicy = JsonNamingPolicy.CamelCase,NumberHandling = JsonNumberHandling.AllowReadingFromString};return JsonSerializer.Deserialize<T>(json, options)!;}record PriceModel(string Symbol, decimal Price);record ExchangeModel(IEnumerable<SymbolModel> Symbols);record SymbolModel(string Symbol, IEnumerable<FilterModel> Filters);record FilterModel(string FilterType, decimal StepSize);using System.Text.Json; using System.Text.Json.Serialization; const string FORMAT = "{0,-15} {1,-8} {2, -8} {3, -20}"; const string PRICE_URL = "https://www.binance.com/fapi/v1/ticker/price"; const string EXCHANGE_INFO_URL = "https://www.binance.com/fapi/v1/exchangeInfo"; const decimal WORK_AMOUNT = 5; Console.WriteLine(FORMAT, "Symbol", "Step", "Rounded", "Initial"); var exchangeModel = await Request<ExchangeModel>(EXCHANGE_INFO_URL); var priceModels = await Request<IEnumerable<PriceModel>>(PRICE_URL); foreach (var model in priceModels) { var step = exchangeModel.Symbols .First(x => x.Symbol == model.Symbol).Filters .First(x => x.FilterType == "LOT_SIZE").StepSize; var initial = WORK_AMOUNT / model.Price; var rounded = Round(initial, step); Console.WriteLine(FORMAT, model.Symbol, step, rounded, initial); } static decimal Round(decimal number, decimal step) { return Math.Floor(number / step) * step; } static async Task<T> Request<T>(string url) { using var client = new HttpClient(); var response = await client.GetAsync(url); response.EnsureSuccessStatusCode(); var json = await response.Content.ReadAsStringAsync(); return Deserialize<T>(json); } static T Deserialize<T>(string json) { var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, NumberHandling = JsonNumberHandling.AllowReadingFromString }; return JsonSerializer.Deserialize<T>(json, options)!; } record PriceModel(string Symbol, decimal Price); record ExchangeModel(IEnumerable<SymbolModel> Symbols); record SymbolModel(string Symbol, IEnumerable<FilterModel> Filters); record FilterModel(string FilterType, decimal StepSize);using System.Text.Json; using System.Text.Json.Serialization; const string FORMAT = "{0,-15} {1,-8} {2, -8} {3, -20}"; const string PRICE_URL = "https://www.binance.com/fapi/v1/ticker/price"; const string EXCHANGE_INFO_URL = "https://www.binance.com/fapi/v1/exchangeInfo"; const decimal WORK_AMOUNT = 5; Console.WriteLine(FORMAT, "Symbol", "Step", "Rounded", "Initial"); var exchangeModel = await Request<ExchangeModel>(EXCHANGE_INFO_URL); var priceModels = await Request<IEnumerable<PriceModel>>(PRICE_URL); foreach (var model in priceModels) { var step = exchangeModel.Symbols .First(x => x.Symbol == model.Symbol).Filters .First(x => x.FilterType == "LOT_SIZE").StepSize; var initial = WORK_AMOUNT / model.Price; var rounded = Round(initial, step); Console.WriteLine(FORMAT, model.Symbol, step, rounded, initial); } static decimal Round(decimal number, decimal step) { return Math.Floor(number / step) * step; } static async Task<T> Request<T>(string url) { using var client = new HttpClient(); var response = await client.GetAsync(url); response.EnsureSuccessStatusCode(); var json = await response.Content.ReadAsStringAsync(); return Deserialize<T>(json); } static T Deserialize<T>(string json) { var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, NumberHandling = JsonNumberHandling.AllowReadingFromString }; return JsonSerializer.Deserialize<T>(json, options)!; } record PriceModel(string Symbol, decimal Price); record ExchangeModel(IEnumerable<SymbolModel> Symbols); record SymbolModel(string Symbol, IEnumerable<FilterModel> Filters); record FilterModel(string FilterType, decimal StepSize);[/spoiler]
[spoiler title="Пример вывода"]<img class="lazyload" src="data:;base64," alt="" width="541" height="487" data-orig-src="https://i.imgur.com/lnry8lt.png" />
[/spoiler]Отлично! На выводе то, что нужно! Только вот я с этим кодом голову сломаю 😂 думал это как-то проще будет 😀
Цитата: Dapofig от 25.01.2023, 22:02Насколько я понимаю, сейчас вся сложность в получении
СкопированоstepSizeпо API. Написал небольшое консольное приложение / пример, которое получает список всех символов,СкопированоstepSizeи печатает пример округления для указанногоСкопированоworkAmount.Кодusing System.Text.Json;using System.Text.Json.Serialization;const string FORMAT = "{0,-15} {1,-8} {2, -8} {3, -20}";const string PRICE_URL = "https://www.binance.com/fapi/v1/ticker/price";const string EXCHANGE_INFO_URL = "https://www.binance.com/fapi/v1/exchangeInfo";const decimal WORK_AMOUNT = 5;Console.WriteLine(FORMAT, "Symbol", "Step", "Rounded", "Initial");var exchangeModel = await Request<ExchangeModel>(EXCHANGE_INFO_URL);var priceModels = await Request<IEnumerable<PriceModel>>(PRICE_URL);foreach (var model in priceModels){var step = exchangeModel.Symbols.First(x => x.Symbol == model.Symbol).Filters.First(x => x.FilterType == "LOT_SIZE").StepSize;var initial = WORK_AMOUNT / model.Price;var rounded = Round(initial, step);Console.WriteLine(FORMAT, model.Symbol, step, rounded, initial);}static decimal Round(decimal number, decimal step){return Math.Floor(number / step) * step;}static async Task<T> Request<T>(string url){using var client = new HttpClient();var response = await client.GetAsync(url);response.EnsureSuccessStatusCode();var json = await response.Content.ReadAsStringAsync();return Deserialize<T>(json);}static T Deserialize<T>(string json){var options = new JsonSerializerOptions{PropertyNamingPolicy = JsonNamingPolicy.CamelCase,NumberHandling = JsonNumberHandling.AllowReadingFromString};return JsonSerializer.Deserialize<T>(json, options)!;}record PriceModel(string Symbol, decimal Price);record ExchangeModel(IEnumerable<SymbolModel> Symbols);record SymbolModel(string Symbol, IEnumerable<FilterModel> Filters);record FilterModel(string FilterType, decimal StepSize);using System.Text.Json; using System.Text.Json.Serialization; const string FORMAT = "{0,-15} {1,-8} {2, -8} {3, -20}"; const string PRICE_URL = "https://www.binance.com/fapi/v1/ticker/price"; const string EXCHANGE_INFO_URL = "https://www.binance.com/fapi/v1/exchangeInfo"; const decimal WORK_AMOUNT = 5; Console.WriteLine(FORMAT, "Symbol", "Step", "Rounded", "Initial"); var exchangeModel = await Request<ExchangeModel>(EXCHANGE_INFO_URL); var priceModels = await Request<IEnumerable<PriceModel>>(PRICE_URL); foreach (var model in priceModels) { var step = exchangeModel.Symbols .First(x => x.Symbol == model.Symbol).Filters .First(x => x.FilterType == "LOT_SIZE").StepSize; var initial = WORK_AMOUNT / model.Price; var rounded = Round(initial, step); Console.WriteLine(FORMAT, model.Symbol, step, rounded, initial); } static decimal Round(decimal number, decimal step) { return Math.Floor(number / step) * step; } static async Task<T> Request<T>(string url) { using var client = new HttpClient(); var response = await client.GetAsync(url); response.EnsureSuccessStatusCode(); var json = await response.Content.ReadAsStringAsync(); return Deserialize<T>(json); } static T Deserialize<T>(string json) { var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, NumberHandling = JsonNumberHandling.AllowReadingFromString }; return JsonSerializer.Deserialize<T>(json, options)!; } record PriceModel(string Symbol, decimal Price); record ExchangeModel(IEnumerable<SymbolModel> Symbols); record SymbolModel(string Symbol, IEnumerable<FilterModel> Filters); record FilterModel(string FilterType, decimal StepSize);using System.Text.Json; using System.Text.Json.Serialization; const string FORMAT = "{0,-15} {1,-8} {2, -8} {3, -20}"; const string PRICE_URL = "https://www.binance.com/fapi/v1/ticker/price"; const string EXCHANGE_INFO_URL = "https://www.binance.com/fapi/v1/exchangeInfo"; const decimal WORK_AMOUNT = 5; Console.WriteLine(FORMAT, "Symbol", "Step", "Rounded", "Initial"); var exchangeModel = await Request<ExchangeModel>(EXCHANGE_INFO_URL); var priceModels = await Request<IEnumerable<PriceModel>>(PRICE_URL); foreach (var model in priceModels) { var step = exchangeModel.Symbols .First(x => x.Symbol == model.Symbol).Filters .First(x => x.FilterType == "LOT_SIZE").StepSize; var initial = WORK_AMOUNT / model.Price; var rounded = Round(initial, step); Console.WriteLine(FORMAT, model.Symbol, step, rounded, initial); } static decimal Round(decimal number, decimal step) { return Math.Floor(number / step) * step; } static async Task<T> Request<T>(string url) { using var client = new HttpClient(); var response = await client.GetAsync(url); response.EnsureSuccessStatusCode(); var json = await response.Content.ReadAsStringAsync(); return Deserialize<T>(json); } static T Deserialize<T>(string json) { var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, NumberHandling = JsonNumberHandling.AllowReadingFromString }; return JsonSerializer.Deserialize<T>(json, options)!; } record PriceModel(string Symbol, decimal Price); record ExchangeModel(IEnumerable<SymbolModel> Symbols); record SymbolModel(string Symbol, IEnumerable<FilterModel> Filters); record FilterModel(string FilterType, decimal StepSize);
Отлично! На выводе то, что нужно! Только вот я с этим кодом голову сломаю 😂 думал это как-то проще будет 😀


