Skip to main content

E.4 Rate Limits, Financial Fields Format, Terms of Service

This section outlines the general rules and requirements for API usage, financial data formatting, and service terms that govern the SSO (OAuth) integration. Compliance with these rules is essential for reliable and secure operation.

Rate Limiting

Rate Limit Policy

Request Limits

  • GET Requests: No rate limits for GET requests
  • PUT/POST/DELETE Requests: Rate limits apply to all modifying requests
  • Threshold: Requests per hour threshold enforced
  • Exceeding Limits: New requests rejected when threshold exceeded

Rate Limit Implementation

// Rate limit response example
{
"error": "Too Many Requests",
"message": "Rate limit exceeded",
"code": "RATE_LIMIT_EXCEEDED",
"details": {
"limit": 1000,
"remaining": 0,
"resetTime": "2023-06-15T11:00:00Z",
"retryAfter": 3600
}
}

Rate Limit Headers

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1686828000
Retry-After: 3600

Best Practices for Rate Limiting

Request Optimization

  • Batch Operations: Combine multiple operations into single requests
  • Efficient Polling: Use appropriate polling intervals
  • Caching: Cache responses to reduce redundant requests
  • Conditional Requests: Use conditional requests when possible

Error Handling

// Rate limit handling
async function makeRequest(url, options = {}) {
try {
const response = await fetch(url, options);

if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After');
const waitTime = retryAfter ? parseInt(retryAfter) * 1000 : 60000;

console.log(`Rate limit exceeded. Waiting ${waitTime}ms...`);
await new Promise(resolve => setTimeout(resolve, waitTime));

return makeRequest(url, options); // Retry request
}

return response;
} catch (error) {
console.error('Request failed:', error);
throw error;
}
}

Exponential Backoff

// Exponential backoff implementation
async function makeRequestWithBackoff(url, options = {}, maxRetries = 3) {
let retryCount = 0;

while (retryCount < maxRetries) {
try {
const response = await fetch(url, options);

if (response.status === 429) {
retryCount++;
const waitTime = Math.min(1000 * Math.pow(2, retryCount), 30000);

console.log(`Rate limit exceeded. Retry ${retryCount}/${maxRetries} in ${waitTime}ms`);
await new Promise(resolve => setTimeout(resolve, waitTime));
continue;
}

return response;
} catch (error) {
if (retryCount === maxRetries - 1) throw error;

retryCount++;
const waitTime = Math.min(1000 * Math.pow(2, retryCount), 30000);
await new Promise(resolve => setTimeout(resolve, waitTime));
}
}
}

Financial Fields Format

Monetary Value Representation

Money Digits Multiplier

Financial fields use a multiplier system for precise decimal representation:

  • Fields Affected: balance, bonus, nonWithdrawableBonus, equity, usedMargin, freeMargin
  • Format: Values listed in 10^moneyDigits
  • Calculation: Actual value = field value / (10^moneyDigits)

Example Calculation

// Example: Equity of 234512 with moneyDigits of 2
const fieldValues = {
equity: 234512,
moneyDigits: 2
};

const actualEquity = fieldValues.equity / Math.pow(10, fieldValues.moneyDigits);
// actualEquity = 234512 / 100 = 2345.12

Financial Data Structure

{
"account": {
"login": 123456,
"balance": 1000000,
"bonus": 50000,
"nonWithdrawableBonus": 25000,
"equity": 1050000,
"usedMargin": 100000,
"freeMargin": 950000,
"moneyDigits": 2,
"currency": "USD"
},
"calculatedValues": {
"balance": 10000.00,
"bonus": 500.00,
"nonWithdrawableBonus": 250.00,
"equity": 10500.00,
"usedMargin": 1000.00,
"freeMargin": 9500.00
}
}

Financial Field Validation

Client-Side Validation

// Financial field validation
function validateFinancialField(value, moneyDigits) {
const errors = [];

// Check if value is a number
if (typeof value !== 'number' || isNaN(value)) {
errors.push('Value must be a valid number');
return { isValid: false, errors };
}

// Check if value is non-negative
if (value < 0) {
errors.push('Value must be non-negative');
}

// Check precision
const maxValue = Number.MAX_SAFE_INTEGER;
if (value > maxValue) {
errors.push('Value exceeds maximum allowed amount');
}

// Calculate actual value for display
const actualValue = value / Math.pow(10, moneyDigits);

return {
isValid: errors.length === 0,
errors,
actualValue,
formattedValue: actualValue.toFixed(moneyDigits)
};
}

Server-Side Validation

// Server-side financial validation
function validateFinancialData(data) {
const requiredFields = ['balance', 'bonus', 'equity', 'usedMargin', 'freeMargin'];
const errors = [];

// Check required fields
requiredFields.forEach(field => {
if (!(field in data)) {
errors.push(`Missing required field: ${field}`);
}
});

// Validate moneyDigits
if (typeof data.moneyDigits !== 'number' || data.moneyDigits < 0 || data.moneyDigits > 8) {
errors.push('moneyDigits must be a number between 0 and 8');
}

// Validate financial fields
requiredFields.forEach(field => {
if (field in data) {
const validation = validateFinancialField(data[field], data.moneyDigits || 2);
if (!validation.isValid) {
errors.push(`${field}: ${validation.errors.join(', ')}`);
}
}
});

return {
isValid: errors.length === 0,
errors
};
}

Currency Handling

Supported Currencies

const supportedCurrencies = [
'USD', 'EUR', 'GBP', 'JPY', 'CHF', 'CAD', 'AUD', 'NZD',
'CNY', 'HKD', 'SGD', 'NOK', 'SEK', 'DKK', 'PLN', 'CZK',
'HUF', 'RON', 'BGN', 'HRK', 'RUB', 'TRY', 'ZAR', 'MXN'
];

function validateCurrency(currency) {
return supportedCurrencies.includes(currency);
}

Currency Formatting

// Currency formatting based on locale
function formatCurrency(amount, currency, locale = 'en-US') {
return new Intl.NumberFormat(locale, {
style: 'currency',
currency: currency,
minimumFractionDigits: 2,
maximumFractionDigits: 2
}).format(amount);
}

// Example usage
formatCurrency(1234.56, 'USD'); // "$1,234.56"
formatCurrency(1234.56, 'EUR', 'de-DE'); // "1.234,56 €"

Terms of Service

API Usage Terms

Acceptance of Terms

By using Spotware's API, brokers automatically agree to the company's terms of service. This includes:

  • Usage Rights: Granted rights for API usage
  • Compliance Requirements: Obligation to comply with all requirements
  • Limitation of Liability: Limitations on Spotware liability
  • Service Level: Service level agreements and expectations

Service Availability

  • Best Effort: Services provided on best effort basis
  • No Guarantee: No guarantee of uninterrupted service
  • Maintenance: Scheduled maintenance may affect availability
  • Emergency Maintenance: Emergency maintenance may be required

Data Usage and Privacy

Data Ownership

  • Broker Data: Brokers retain ownership of their data
  • User Data: User data protection and privacy requirements
  • Analytics Data: Analytics data usage and sharing policies
  • Compliance: Compliance with data protection regulations

Data Security

  • Encryption: Data encryption requirements
  • Access Control: Access control and authentication requirements
  • Audit Trail: Audit trail maintenance requirements
  • Breach Notification: Security breach notification requirements

Regulatory Compliance

  • Financial Regulations: Compliance with financial regulations
  • Data Protection: GDPR and other data protection compliance
  • AML/KYC: Anti-money laundering and know-your-customer requirements
  • Reporting: Regulatory reporting requirements
  • Jurisdiction: Applicable legal jurisdictions
  • Dispute Resolution: Dispute resolution processes
  • Governing Law: Governing law and legal framework
  • Intellectual Property: Intellectual property rights and usage

Technical Requirements

Security Standards

  • HTTPS Required: All API calls must use HTTPS
  • Authentication: Proper authentication mechanisms required
  • Authorization: Appropriate authorization controls required
  • Data Protection: Data protection measures required

Performance Standards

  • Response Times: Expected response time standards
  • Availability: Service availability targets
  • Scalability: Scalability requirements and expectations
  • Monitoring: Monitoring and alerting requirements

Implementation Guidelines

Error Handling for Financial Data

Financial Error Responses

{
"error": "Financial Data Error",
"message": "Invalid financial data format",
"code": "INVALID_FINANCIAL_DATA",
"details": {
"field": "balance",
"value": "invalid_value",
"expectedFormat": "numeric value in 10^moneyDigits format",
"moneyDigits": 2
}
}

Financial Error Handling

function handleFinancialError(error) {
switch (error.code) {
case 'INVALID_FINANCIAL_DATA':
console.error('Financial data validation failed:', error.details);
// Display user-friendly error message
showUserError('Invalid financial data. Please check your input.');
break;

case 'INSUFFICIENT_FUNDS':
console.error('Insufficient funds for operation');
showUserError('Insufficient funds for this operation.');
break;

case 'CURRENCY_NOT_SUPPORTED':
console.error('Unsupported currency:', error.details.currency);
showUserError('Currency not supported. Please use a different currency.');
break;

default:
console.error('Unknown financial error:', error);
showUserError('An error occurred. Please try again.');
}
}

Rate Limiting Implementation

Client-Side Rate Limiting

class RateLimiter {
constructor(maxRequests, timeWindow) {
this.maxRequests = maxRequests;
this.timeWindow = timeWindow;
this.requests = [];
}

async makeRequest(requestFn) {
const now = Date.now();

// Remove old requests outside time window
this.requests = this.requests.filter(time => now - time < this.timeWindow);

// Check if rate limit exceeded
if (this.requests.length >= this.maxRequests) {
const oldestRequest = Math.min(...this.requests);
const waitTime = this.timeWindow - (now - oldestRequest);

console.log(`Rate limit reached. Waiting ${waitTime}ms...`);
await new Promise(resolve => setTimeout(resolve, waitTime));
}

// Make request
this.requests.push(now);
return requestFn();
}
}

// Usage
const rateLimiter = new RateLimiter(100, 60000); // 100 requests per minute

async function apiCall(url, options) {
return rateLimiter.makeRequest(async () => {
const response = await fetch(url, options);
return response;
});
}

Financial Data Processing

Financial Calculations

class FinancialCalculator {
constructor(moneyDigits = 2) {
this.moneyDigits = moneyDigits;
this.multiplier = Math.pow(10, moneyDigits);
}

toFieldValue(actualValue) {
return Math.round(actualValue * this.multiplier);
}

toActualValue(fieldValue) {
return fieldValue / this.multiplier;
}

formatFieldValue(fieldValue) {
const actualValue = this.toActualValue(fieldValue);
return actualValue.toFixed(this.moneyDigits);
}

calculateFreeMargin(equity, usedMargin) {
const actualEquity = this.toActualValue(equity);
const actualUsedMargin = this.toActualValue(usedMargin);
const actualFreeMargin = actualEquity - actualUsedMargin;
return this.toFieldValue(actualFreeMargin);
}

calculateMarginLevel(equity, usedMargin) {
const actualEquity = this.toActualValue(equity);
const actualUsedMargin = this.toActualValue(usedMargin);

if (actualUsedMargin === 0) return 0;

return (actualEquity / actualUsedMargin) * 100;
}
}

// Usage
const calculator = new FinancialCalculator(2);
const balance = calculator.toFieldValue(10000.50); // 1000050
const actualBalance = calculator.toActualValue(balance); // 10000.50
const formattedBalance = calculator.formatFieldValue(balance); // "10000.50"

Monitoring and Compliance

API Usage Monitoring

  • Request Tracking: Track all API requests and responses
  • Rate Limit Monitoring: Monitor rate limit compliance
  • Error Tracking: Track and analyze API errors
  • Performance Monitoring: Monitor API performance metrics

Financial Data Monitoring

  • Data Validation: Continuous validation of financial data
  • Accuracy Checks: Regular accuracy checks and audits
  • Compliance Monitoring: Monitor compliance with financial regulations
  • Anomaly Detection: Detect and investigate anomalies

Compliance Monitoring

  • Terms Compliance: Monitor compliance with terms of service
  • Regulatory Compliance: Monitor regulatory compliance
  • Security Compliance: Monitor security compliance
  • Privacy Compliance: Monitor privacy compliance

Best Practices

Rate Limiting Best Practices

  • Respect Limits: Always respect rate limit headers
  • Implement Backoff: Use exponential backoff for retries
  • Cache Responses: Cache responses to reduce requests
  • Batch Operations: Use batch operations when possible

Financial Data Best Practices

  • Precision: Maintain appropriate precision for financial calculations
  • Validation: Always validate financial data
  • Error Handling: Handle financial errors gracefully
  • Audit Trail: Maintain complete audit trail for financial operations

Compliance Best Practices

  • Regular Review: Regularly review compliance status
  • Documentation: Maintain comprehensive documentation
  • Training: Train staff on compliance requirements
  • Monitoring: Continuous monitoring of compliance status

This comprehensive framework ensures proper API usage, accurate financial data handling, and compliance with all terms and regulatory requirements for SSO (OAuth) integration.