VERSION 1.14 @ 2019-04-04 08:32:01.655131
x axis retains previous scale after restoring layout #3828 getVisiblePriceRange() not working in 1.14 (unstable) #3774 uppercase_instrument_names doesn't work for compare/overlay #3746 API method to trigger the Zoom Out #3739 Provide event that study properties was changed #3736 Fixed security issue in master #3699 widget.save have old data #3623 JS error on switching chart types #3602 Add a way to prevent scrolling beyond the beginning of bars #3597 Chart customization - overrides #3572 Theme override colors from saved_data #3557 Error while applying Pivot Points Indicator #3521 Month timeframe combining months #3510 initialSettings from settings adapter does not work #3479 Add Indexed to 100 mode for price scale #3391 RTL #3335 Add warning about incorrect usage disable_resolution_rebuild and has_empty_bars #3329 Unable to load DOME and Bottom Widget when open_account_manager disabled #3312 Randomly clickable area on chart that redirects user to tradingview.com #3299 Apply to all #3298 Save container element while charting library's life #3297 Gap appearing in chart layout #3246 User's colors not working when theme is enabled #3232 Chart is outside of visible range when in auto scale and load study template or load chart #3229 Please make getVisibleRange return the range in UTC #3173 Remove TradingView.onready from API #3162 Add API to export data from the chart #3152 Market status is not updated properly #3122 Placeholders disappear in "Compare or Add Symbol" popup when the cursor is set into the fields #2966 getVisibleRange to return 0, any way of getting the last bar in active chart ? #2757 "onListAdded" event is not fired when user click on "Save Watchlist As" #2654 Error report : Parabolic SAR #2205 TERMINAL: make a flag to disable support of stop orders #2181 Add Change % in the OHLC label Charting Library #2120 Request more bars for indicators #1362 Drawing tool does not work on Samsung Edge and Note 5 #984
This commit is contained in:
243
datafeeds/udf/src/udf-compatible-datafeed-base.js
Normal file
243
datafeeds/udf/src/udf-compatible-datafeed-base.js
Normal file
@@ -0,0 +1,243 @@
|
||||
import { getErrorMessage, logMessage, } from './helpers';
|
||||
import { HistoryProvider, } from './history-provider';
|
||||
import { DataPulseProvider } from './data-pulse-provider';
|
||||
import { QuotesPulseProvider } from './quotes-pulse-provider';
|
||||
import { SymbolsStorage } from './symbols-storage';
|
||||
function extractField(data, field, arrayIndex) {
|
||||
var value = data[field];
|
||||
return Array.isArray(value) ? value[arrayIndex] : value;
|
||||
}
|
||||
/**
|
||||
* This class implements interaction with UDF-compatible datafeed.
|
||||
* See UDF protocol reference at https://github.com/tradingview/charting_library/wiki/UDF
|
||||
*/
|
||||
var UDFCompatibleDatafeedBase = /** @class */ (function () {
|
||||
function UDFCompatibleDatafeedBase(datafeedURL, quotesProvider, requester, updateFrequency) {
|
||||
if (updateFrequency === void 0) { updateFrequency = 10 * 1000; }
|
||||
var _this = this;
|
||||
this._configuration = defaultConfiguration();
|
||||
this._symbolsStorage = null;
|
||||
this._datafeedURL = datafeedURL;
|
||||
this._requester = requester;
|
||||
this._historyProvider = new HistoryProvider(datafeedURL, this._requester);
|
||||
this._quotesProvider = quotesProvider;
|
||||
this._dataPulseProvider = new DataPulseProvider(this._historyProvider, updateFrequency);
|
||||
this._quotesPulseProvider = new QuotesPulseProvider(this._quotesProvider);
|
||||
this._configurationReadyPromise = this._requestConfiguration()
|
||||
.then(function (configuration) {
|
||||
if (configuration === null) {
|
||||
configuration = defaultConfiguration();
|
||||
}
|
||||
_this._setupWithConfiguration(configuration);
|
||||
});
|
||||
}
|
||||
UDFCompatibleDatafeedBase.prototype.onReady = function (callback) {
|
||||
var _this = this;
|
||||
this._configurationReadyPromise.then(function () {
|
||||
callback(_this._configuration);
|
||||
});
|
||||
};
|
||||
UDFCompatibleDatafeedBase.prototype.getQuotes = function (symbols, onDataCallback, onErrorCallback) {
|
||||
this._quotesProvider.getQuotes(symbols).then(onDataCallback).catch(onErrorCallback);
|
||||
};
|
||||
UDFCompatibleDatafeedBase.prototype.subscribeQuotes = function (symbols, fastSymbols, onRealtimeCallback, listenerGuid) {
|
||||
this._quotesPulseProvider.subscribeQuotes(symbols, fastSymbols, onRealtimeCallback, listenerGuid);
|
||||
};
|
||||
UDFCompatibleDatafeedBase.prototype.unsubscribeQuotes = function (listenerGuid) {
|
||||
this._quotesPulseProvider.unsubscribeQuotes(listenerGuid);
|
||||
};
|
||||
UDFCompatibleDatafeedBase.prototype.calculateHistoryDepth = function (resolution, resolutionBack, intervalBack) {
|
||||
return undefined;
|
||||
};
|
||||
UDFCompatibleDatafeedBase.prototype.getMarks = function (symbolInfo, from, to, onDataCallback, resolution) {
|
||||
if (!this._configuration.supports_marks) {
|
||||
return;
|
||||
}
|
||||
var requestParams = {
|
||||
symbol: symbolInfo.ticker || '',
|
||||
from: from,
|
||||
to: to,
|
||||
resolution: resolution,
|
||||
};
|
||||
this._send('marks', requestParams)
|
||||
.then(function (response) {
|
||||
if (!Array.isArray(response)) {
|
||||
var result = [];
|
||||
for (var i = 0; i < response.id.length; ++i) {
|
||||
result.push({
|
||||
id: extractField(response, 'id', i),
|
||||
time: extractField(response, 'time', i),
|
||||
color: extractField(response, 'color', i),
|
||||
text: extractField(response, 'text', i),
|
||||
label: extractField(response, 'label', i),
|
||||
labelFontColor: extractField(response, 'labelFontColor', i),
|
||||
minSize: extractField(response, 'minSize', i),
|
||||
});
|
||||
}
|
||||
response = result;
|
||||
}
|
||||
onDataCallback(response);
|
||||
})
|
||||
.catch(function (error) {
|
||||
logMessage("UdfCompatibleDatafeed: Request marks failed: " + getErrorMessage(error));
|
||||
onDataCallback([]);
|
||||
});
|
||||
};
|
||||
UDFCompatibleDatafeedBase.prototype.getTimescaleMarks = function (symbolInfo, from, to, onDataCallback, resolution) {
|
||||
if (!this._configuration.supports_timescale_marks) {
|
||||
return;
|
||||
}
|
||||
var requestParams = {
|
||||
symbol: symbolInfo.ticker || '',
|
||||
from: from,
|
||||
to: to,
|
||||
resolution: resolution,
|
||||
};
|
||||
this._send('timescale_marks', requestParams)
|
||||
.then(function (response) {
|
||||
if (!Array.isArray(response)) {
|
||||
var result = [];
|
||||
for (var i = 0; i < response.id.length; ++i) {
|
||||
result.push({
|
||||
id: extractField(response, 'id', i),
|
||||
time: extractField(response, 'time', i),
|
||||
color: extractField(response, 'color', i),
|
||||
label: extractField(response, 'label', i),
|
||||
tooltip: extractField(response, 'tooltip', i),
|
||||
});
|
||||
}
|
||||
response = result;
|
||||
}
|
||||
onDataCallback(response);
|
||||
})
|
||||
.catch(function (error) {
|
||||
logMessage("UdfCompatibleDatafeed: Request timescale marks failed: " + getErrorMessage(error));
|
||||
onDataCallback([]);
|
||||
});
|
||||
};
|
||||
UDFCompatibleDatafeedBase.prototype.getServerTime = function (callback) {
|
||||
if (!this._configuration.supports_time) {
|
||||
return;
|
||||
}
|
||||
this._send('time')
|
||||
.then(function (response) {
|
||||
var time = parseInt(response);
|
||||
if (!isNaN(time)) {
|
||||
callback(time);
|
||||
}
|
||||
})
|
||||
.catch(function (error) {
|
||||
logMessage("UdfCompatibleDatafeed: Fail to load server time, error=" + getErrorMessage(error));
|
||||
});
|
||||
};
|
||||
UDFCompatibleDatafeedBase.prototype.searchSymbols = function (userInput, exchange, symbolType, onResult) {
|
||||
if (this._configuration.supports_search) {
|
||||
var params = {
|
||||
limit: 30 /* SearchItemsLimit */,
|
||||
query: userInput.toUpperCase(),
|
||||
type: symbolType,
|
||||
exchange: exchange,
|
||||
};
|
||||
this._send('search', params)
|
||||
.then(function (response) {
|
||||
if (response.s !== undefined) {
|
||||
logMessage("UdfCompatibleDatafeed: search symbols error=" + response.errmsg);
|
||||
onResult([]);
|
||||
return;
|
||||
}
|
||||
onResult(response);
|
||||
})
|
||||
.catch(function (reason) {
|
||||
logMessage("UdfCompatibleDatafeed: Search symbols for '" + userInput + "' failed. Error=" + getErrorMessage(reason));
|
||||
onResult([]);
|
||||
});
|
||||
}
|
||||
else {
|
||||
if (this._symbolsStorage === null) {
|
||||
throw new Error('UdfCompatibleDatafeed: inconsistent configuration (symbols storage)');
|
||||
}
|
||||
this._symbolsStorage.searchSymbols(userInput, exchange, symbolType, 30 /* SearchItemsLimit */)
|
||||
.then(onResult)
|
||||
.catch(onResult.bind(null, []));
|
||||
}
|
||||
};
|
||||
UDFCompatibleDatafeedBase.prototype.resolveSymbol = function (symbolName, onResolve, onError) {
|
||||
logMessage('Resolve requested');
|
||||
var resolveRequestStartTime = Date.now();
|
||||
function onResultReady(symbolInfo) {
|
||||
logMessage("Symbol resolved: " + (Date.now() - resolveRequestStartTime) + "ms");
|
||||
onResolve(symbolInfo);
|
||||
}
|
||||
if (!this._configuration.supports_group_request) {
|
||||
var params = {
|
||||
symbol: symbolName,
|
||||
};
|
||||
this._send('symbols', params)
|
||||
.then(function (response) {
|
||||
if (response.s !== undefined) {
|
||||
onError('unknown_symbol');
|
||||
}
|
||||
else {
|
||||
onResultReady(response);
|
||||
}
|
||||
})
|
||||
.catch(function (reason) {
|
||||
logMessage("UdfCompatibleDatafeed: Error resolving symbol: " + getErrorMessage(reason));
|
||||
onError('unknown_symbol');
|
||||
});
|
||||
}
|
||||
else {
|
||||
if (this._symbolsStorage === null) {
|
||||
throw new Error('UdfCompatibleDatafeed: inconsistent configuration (symbols storage)');
|
||||
}
|
||||
this._symbolsStorage.resolveSymbol(symbolName).then(onResultReady).catch(onError);
|
||||
}
|
||||
};
|
||||
UDFCompatibleDatafeedBase.prototype.getBars = function (symbolInfo, resolution, rangeStartDate, rangeEndDate, onResult, onError) {
|
||||
this._historyProvider.getBars(symbolInfo, resolution, rangeStartDate, rangeEndDate)
|
||||
.then(function (result) {
|
||||
onResult(result.bars, result.meta);
|
||||
})
|
||||
.catch(onError);
|
||||
};
|
||||
UDFCompatibleDatafeedBase.prototype.subscribeBars = function (symbolInfo, resolution, onTick, listenerGuid, onResetCacheNeededCallback) {
|
||||
this._dataPulseProvider.subscribeBars(symbolInfo, resolution, onTick, listenerGuid);
|
||||
};
|
||||
UDFCompatibleDatafeedBase.prototype.unsubscribeBars = function (listenerGuid) {
|
||||
this._dataPulseProvider.unsubscribeBars(listenerGuid);
|
||||
};
|
||||
UDFCompatibleDatafeedBase.prototype._requestConfiguration = function () {
|
||||
return this._send('config')
|
||||
.catch(function (reason) {
|
||||
logMessage("UdfCompatibleDatafeed: Cannot get datafeed configuration - use default, error=" + getErrorMessage(reason));
|
||||
return null;
|
||||
});
|
||||
};
|
||||
UDFCompatibleDatafeedBase.prototype._send = function (urlPath, params) {
|
||||
return this._requester.sendRequest(this._datafeedURL, urlPath, params);
|
||||
};
|
||||
UDFCompatibleDatafeedBase.prototype._setupWithConfiguration = function (configurationData) {
|
||||
this._configuration = configurationData;
|
||||
if (configurationData.exchanges === undefined) {
|
||||
configurationData.exchanges = [];
|
||||
}
|
||||
if (!configurationData.supports_search && !configurationData.supports_group_request) {
|
||||
throw new Error('Unsupported datafeed configuration. Must either support search, or support group request');
|
||||
}
|
||||
if (configurationData.supports_group_request || !configurationData.supports_search) {
|
||||
this._symbolsStorage = new SymbolsStorage(this._datafeedURL, configurationData.supported_resolutions || [], this._requester);
|
||||
}
|
||||
logMessage("UdfCompatibleDatafeed: Initialized with " + JSON.stringify(configurationData));
|
||||
};
|
||||
return UDFCompatibleDatafeedBase;
|
||||
}());
|
||||
export { UDFCompatibleDatafeedBase };
|
||||
function defaultConfiguration() {
|
||||
return {
|
||||
supports_search: false,
|
||||
supports_group_request: true,
|
||||
supported_resolutions: ['1', '5', '15', '30', '60', '1D', '1W', '1M'],
|
||||
supports_marks: false,
|
||||
supports_timescale_marks: false,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user