I'm using the Weather API to pull weather information down as a service for my project. I'm trying to understand some timezone offsets that I can't seem to find information on.
The URL I'm using is:
https://api.weather.gov/gridpoints/VEF/154,48
Here is some sample return values:
"temperature": {
"sourceUnit": "F",
"uom": "unit:degC",
"values": [
{
"validTime": "2019-05-11T16:00:00+00:00/PT1H",
"value": 18.333333333333371
},
{
"validTime": "2019-05-12T04:00:00+00:00/PT2H",
"value": 16.1111111111112
},
{
"validTime": "2019-05-12T21:00:00+00:00/PT4H",
"value": 26.666666666666742
},
...
]
}
I understand the PT means Pacific Timezone. But I cant seem to find any information on the next to characters like 1H, 2H, etc.
If anyone can advise that would be appreciated - Thanks
PT1H = One hour
I understand the PT means Pacific Timezone.
No, incorrect assumption. Not a time zone.
The PT1H represents a duration, a span of time not tied to the timeline. This format is defined in the ISO 8601 standard.
The P marks the beginning, short for “Period” I imagine, a synonym for duration. The T separates any years-months-days portion from any hours-minutes-seconds portion.
So PT1H means “one hour”. Two and a half hours would be PT2H30M.
Parsing
Your input "2019-05-11T16:00:00+00:00/PT1H" combining a starting moment with a duration is part of the ISO 8601 standard.
Such a combo string can be parsed by the Interval.parse method found in the ThreeTen-Extra library.
Interval interval = Interval.parse( "2019-05-11T16:00:00+00:00/PT1H" ) ;
An Interval represents a pair of moments, a pair of Instant objects. In your case here, the second moment is calculated, by adding the duration to the starting moment. We can interrogate for the pair of moments, represented as Instant objects (always in UTC by definition).
Instant start = interval.getStart() ;
Instant stop = interval.getEnd() ;
Related
Trying to hit the fapi.binance.com/fapi/v1/exchangeInfo endpoint in order to get the current minimum order quantity for a pair (let's take ETHUSDT as an example).
Here is what Binance UI shows as the minQty: Minimum order quantity for ETH is 0.004ETH
When hitting the above mentioned endpoint and inspecting the ETHUSDT symbol specific response:
{
"symbol": "ETHUSDT",
"pair": "ETHUSDT",
"contractType": "PERPETUAL",
"deliveryDate": 4133404800000,
"onboardDate": 1569398400000,
"status": "TRADING",
"maintMarginPercent": "2.5000",
"requiredMarginPercent": "5.0000",
"baseAsset": "ETH",
"quoteAsset": "USDT",
"marginAsset": "USDT",
"pricePrecision": 2,
"quantityPrecision": 3,
"baseAssetPrecision": 8,
"quotePrecision": 8,
"underlyingType": "COIN",
"underlyingSubType": [
"Layer-1"
],
"settlePlan": 0,
"triggerProtect": "0.0500",
"liquidationFee": "0.015000",
"marketTakeBound": "0.05",
"filters": [
{
"minPrice": "39.86",
"maxPrice": "306177",
"filterType": "PRICE_FILTER",
"tickSize": "0.01"
},
{
"stepSize": "0.001",
"filterType": "LOT_SIZE",
"maxQty": "10000",
"minQty": "0.001"
},
{
"stepSize": "0.001",
"filterType": "MARKET_LOT_SIZE",
"maxQty": "2000",
"minQty": "0.001"
},
{
"limit": 200,
"filterType": "MAX_NUM_ORDERS"
},
{
"limit": 10,
"filterType": "MAX_NUM_ALGO_ORDERS"
},
{
"notional": "5",
"filterType": "MIN_NOTIONAL"
},
{
"multiplierDown": "0.9500",
"multiplierUp": "1.0500",
"multiplierDecimal": "4",
"filterType": "PERCENT_PRICE"
}
],
"orderTypes": [
"LIMIT",
"MARKET",
"STOP",
"STOP_MARKET",
"TAKE_PROFIT",
"TAKE_PROFIT_MARKET",
"TRAILING_STOP_MARKET"
],
"timeInForce": [
"GTC",
"IOC",
"FOK",
"GTX"
]
}
We can observe that no data here indicates a correct minQty despite the fact that some documents in the filters array (like LOT_SIZE and MARKET_LOT_SIZE) are trying.
Am I missing something or is this a Binance API bug?
Took a while to figure it out, but I believe I have come to a solution/explanation.
As I previously noted, we are interested in the filters array found in the response of the fapi.binance.com/fapi/v1/exchangeInfo endpoint, specifically the MARKET_LOT_SIZE (LOT_SIZE if you are not interested in market orders) and MIN_NOTIONAL filters. When I wrote the question I assumed one of those had to be the source of truth, but none of the two were consistently matching the minimum order quantities seen on Binance UI.
It turns out its not one of them, but the two combined...sort of.
For inexperienced traders - a quick definition. Base asset - the asset you are buying. Quote asset - the asset you are acquiring the base asset with. In my case (ETHUSDT) ETH was the base asset and USDT was the quote asset.
MIN_NOTIONAL filter tells you the minimum amount of the quote asset you are required to spend to acquire the base asset. This filter is equal to 5 USDT in the case of ETHUSDT at the time of posting.
MARKET_LOT_SIZE filter tells you the minimum amount of the base asset you can buy. This filter is equal to 0.001 in the case of ETHUSDT at the time of posting.
Depending on the price of ETH, 0.001 ETH may cost less than 5 USDT, which would not fill the MIN_NOTIONAL filter's requirement. Similarly, if, due to price, 5 USDT bought less than 0.001 ETH, an order with notional value of 5 USDT would not fill the requirement of the MARKET_LOT_SIZE filter.
Hence, to calculate the minimum order quantity, we need to take the maximum value of the two with one caveat. We first need to convert the MIN_NOTIONAL filter value of 5 USDT to ETH. We can do that by dividing that value by the current price of ETH. Beware, if the result of the division has more decimal points then the quantity precision of the asset on Binance, we need to round up to that number of decimals.
Ultimately, the calculation example in Python:
max(
MIN_MARKET_LOT_SIZE,
round_up((MIN_NOTIONAL / CURRENT_ETH_PRICE), ETH_QUANTITY_PRECISION)
)
An example of the decimal rounding up function can be found here
Below calculation worked for me.
Divide MIN_NOTIONAL value with the current price of symbol to get the minimum quantity to place the order
minQty = MIN_NOTIONAL / current price of symbol
In my case,
MIN_NOTIONAL value was 5.0,
I have used 5.5, just to place the order more than the minimum quantity
use um_futures_client.mark_price(symbol) to get the mark price
Thanks
I am trying to learn F# and was wondering if i have a json object which has time in microseconds as int. I want to get the day, date and time out of this and was wondering how to do it.
I actually happen to have needed to do this recently. You'll almost certainly want to use the .NET time objects (DateTime, DateTimeOffset, TimeSpan) in some capacity. Here's what I went with:
let TicksPerMicrosecond =
TimeSpan.TicksPerMillisecond / 1000L
let FromUnixTimeMicroseconds (us: int64) =
DateTimeOffset.FromUnixTimeMilliseconds 0L + TimeSpan.FromTicks(us * TicksPerMicrosecond)
From TimeSpan.TicksPerMillisecond we can calculate how many are in a microsecond (if I remember correctly it's 10, but this way it doesn't seem as "magic"). Then I can convert the microseconds value into ticks and add it to the epoch date.
To get the day of the week (assuming the time zone is UTC), you'd just use DateTimeOffset.DayOfWeek.
I'm getting a bit stuck with a piece of mql4 code. Esentially, I need to access and store the OHLC prices of a historic bar back in time maximum 30 days back from current date. This is how I am currently doing it.
input int referenceDay=1;
static double reference;
if ( Day() == referenceDay ) reference = Open[0];
This is working fine until the point I either add to the code which, it then resets the reference back to 0. I am looking for a way to be able to access the history on each new candle and store the price for the referenceDay.
The objective is that whenever the EA is loaded to the chart, it automatically goes into the history and updates the reference price to be used on this trading day without having to wait for the entire month's iteration in real time.
The objective is that whenever the EA is loaded to the chart, it automatically goes into the history and updates the reference price
So far so good.
Once EA gets loaded,
the definition of static double reference; sets the initial value of reference == 0.;
next, the call to Day() sets the rules:
int Day(); returns the current day of the month, which is not the "today"'s-day, but the day of month of the so called last known server time. Given the EA was loaded on Sunday afternoon, or Monday morning, before the Market was opened, the "last known server time" is still Friday ... remember, the Server-side datetime rules ( so, if trading on APAC or Australia / New Zealand TimeZone servers, additional gymnastics are in place ).
So, as the code continues - in all such cases, when the input int referenceDay value will accidentally != the last known server time Day(), your ( just ) initialised variable reference will remain == 0.
Surprised?
May test it:
static double reference = EMPTY; // .SET EXPLICIT INITIALISER
if ( Day() == referenceDay )
{ reference = Open[0];
print( reference,
"AFTER Day() MATCHED referenceDay" // THIS NEED NOT HAPPEN
);
}
else
{ print( reference,
"ON( ",Day(), " ) ",
"AFTER Day() DID NOT MATCH referenceDay = ",
referenceDay
}
May redefine the assignment strategy, using:
input int referenceDAYinput = 1;
int referenceDAYnDaysBACK = max( 0, // FUSED
Day() - referenceDAYinput
);
static double referenceLEVEL = iOpen( _Symbol,
PERIOD_D1,
referenceDAYnDaysBACK
);
This code snippet certainly does not strive to be the complete solution, but shows the mechanics for achieving the desired objective.
Your actual code will have to solve how many Trading days - which is needed to address the TimeSeries-indexing logic of MetaTrader Terminal 4 platofrm -- ( not just the Calendar days ) -- there were in between the referenceDAYinput and the "last known server time"-Day(), but your are this close to have this done.
Two computer install centos 6.5, kernel is 3.10.44, have different result.
one result is [u'Asia/Shanghai', u'Asia/Urumqi'], and the other is ['Asia/Shanghai', 'Asia/Harbin', 'Asia/Chongqing', 'Asia/Urumqi', 'Asia/Kashgar'].
Is there any config that make the first result same as the second result?
I have following python code:
def get_date():
date = datetime.utcnow()
from_zone = pytz.timezone("UTC")
to_zone = pytz.timezone("Asia/Urumqi")
date = from_zone.localize(date)
date = date.astimezone(to_zone)
return date
def get_curr_time_stamp():
date = get_date()
stamp = time.mktime(date.timetuple())
return stamp
cur_time = get_curr_time_stamp()
print "1", time.strftime("%Y %m %d %H:%M:%S", time.localtime(time.time()))
print "2", time.strftime("%Y %m %d %H:%M:%S", time.localtime(cur_time))
When use this code to get time, the result of one computer(have 2 results) is:
1 2016 04 20 08:53:18
2 2016 04 20 06:53:18
and the other(have 5 results) is:
1 2016 04 20 08:53:18
2 2016 04 20 08:53:18
I don't know why?
You probably just have an outdated version of pytz on the system returning five time zones (or perhaps on both systems). You can find the latest releases here. It's important to stay on top of time zone updates, as the various governments of the world change their time zones often.
Like most systems, pytz gets its data from the tz database. The five time zones for China were reduced to two in version 2014f (corresponding to pytz 2014.6). From the release notes:
China's five zones have been simplified to two, since the post-1970
differences in the other three seem to have been imaginary. The
zones Asia/Harbin, Asia/Chongqing, and Asia/Kashgar have been
removed; backwards-compatibility links still work, albeit with
different behaviors for time stamps before May 1980. Asia/Urumqi's
1980 transition to UTC+8 has been removed, so that it is now at
UTC+6 and not UTC+8. (Thanks to Luther Ma and to Alois Treindl;
Treindl sent helpful translations of two papers by Guo Qingsheng.)
Also, you may wish to read Wikipedia's Time in China article, which explains that the Asia/Urumqui entry is for "Ürümqi Time", which is used unofficially in some parts of the Xinjiang region. This zone is not recognized by the Chinese government, and is considered a politically charged issue. As such, many systems choose to omit the Urumqi time zone, despite it being in listed in the tz database.
I'm trying to parse a full ISO8601 datetime from JSON data in Lua.
I'm having trouble with the match pattern.
So far, this is what I have:
-- Example datetime string 2011-10-25T00:29:55.503-04:00
local datetime = "2011-10-25T00:29:55.503-04:00"
local pattern = "(%d+)%-(%d+)%-(%d+)T(%d+):(%d+):(%d+)%.(%d+)"
local xyear, xmonth, xday, xhour, xminute,
xseconds, xmillies, xoffset = datetime:match(pattern)
local convertedTimestamp = os.time({year = xyear, month = xmonth,
day = xday, hour = xhour, min = xminute, sec = xseconds})
I'm stuck at how to deal with the timezone on the pattern because there is no logical or that will handle the - or + or none.
Although I know lua doesn't support the timezone in the os.time function, at least I would know how it needed to be adjusted.
I've considered stripping off everything after the "." (milliseconds and timezone), but then i really wouldn't have a valid datetime. Milliseconds is not all that important and i wouldn't mind losing it, but the timezone changes things.
Note: Somebody may have some much better code for doing this and I'm not married to it, I just need to get something useful out of the datetime string :)
The full ISO 8601 format can't be done with a single pattern match. There is too much variation.
Some examples from the wikipedia page:
There is a "compressed" format that doesn't separate numbers: YYYYMMDD vs YYYY-MM-DD
The day can be omited: YYYY-MM-DD and YYYY-MM are both valid dates
The ordinal date is also valid: YYYY-DDD, where DDD is the day of the year (1-365/6)
When representing the time, the minutes and seconds can be ommited: hh:mm:ss, hh:mm and hh are all valid times
Moreover, time also has a compressed version: hhmmss, hhmm
And on top of that, time accepts fractions, using both the dot or the comma to denote fractions of the lower time element in the time section. 14:30,5, 1430,5, 14:30.5, or 1430.5 all represent 14 hours, 30 seconds and a half.
Finally, the timezone section is optional. When present, it can be either the letter Z, ±hh:mm, ±hh or ±hhmm.
So, there are lots of possible exceptions to take into account, if you are going to parse according to the full spec. In that case, your initial code might look like this:
function parseDateTime(str)
local Y,M,D = parseDate(str)
local h,m,s = parseTime(str)
local oh,om = parseOffset(str)
return os.time({year=Y, month=M, day=D, hour=(h+oh), min=(m+om), sec=s})
end
And then you would have to create parseDate, parseTime and parseOffset. The later should return the time offsets from UTC, while the first two would have to take into account things like compressed formats, time fractions, comma or dot separators, and the like.
parseDate will likely use the "^" character at the beginning of its pattern matches, since the date has to be at the beginning of the string. parseTime's patterns will likely start with "T". And parseOffset's will end with "$", since the time offsets, when they exist, are at the end.
A "full ISO" parseOffset function might look similar to this:
function parseOffset(str)
if str:sub(-1)=="Z" then return 0,0 end -- ends with Z, Zulu time
-- matches ±hh:mm, ±hhmm or ±hh; else returns nils
local sign, oh, om = str:match("([-+])(%d%d):?(%d?%d?)$")
sign, oh, om = sign or "+", oh or "00", om or "00"
return tonumber(sign .. oh), tonumber(sign .. om)
end
By the way, I'm assuming that your computer is working in UTC time. If that's not the case, you will have to include an additional offset on your hours/minutes to account for that.
function parseDateTime(str)
local Y,M,D = parseDate(str)
local h,m,s = parseTime(str)
local oh,om = parseOffset(str)
local loh,lom = getLocalUTCOffset()
return os.time({year=Y, month=M, day=D, hour=(h+oh-loh), min=(m+om-lom), sec=s})
end
To get your local offset you might want to look at http://lua-users.org/wiki/TimeZone .
I hope this helps. Regards!
There is also the luadate package, which supports iso8601. (You probably want the patched version)
Here is a simple parseDate function for ISO dates. Note that I'm using "now" as a fallback. This may or may not work for you. YMMV 😉.
--[[
Parse date given in any of supported forms.
Note! For unrecognised format will return now.
#param str ISO date. Formats:
Y-m-d
Y-m -- this will assume January
Y -- this will assume 1st January
]]
function parseDate(str)
local y, m, d = str:match("(%d%d%d%d)-?(%d?%d?)-?(%d?%d?)$")
-- fallback to now
if y == nil then
return os.time()
end
-- defaults
if m == '' then
m = 1
end
if d == '' then
d = 1
end
-- create time
return os.time{year=y, month=m, day=d, hour=0}
end
--[[
--Tests:
print( os.date( "%Y-%m-%d", parseDate("2019-12-28") ) )
print( os.date( "%Y-%m-%d", parseDate("2019-12") ) )
print( os.date( "%Y-%m-%d", parseDate("2019") ) )
]]