Add Historial CalendarPrices Chart
This commit is contained in:
+21
-30
@@ -2,48 +2,38 @@ import Header from './Header';
|
||||
import { HistoricalImpliedVolatilityChart } from "./HistoricalImpliedVolatilityChart";
|
||||
import { Picker } from './Picker';
|
||||
import { atom as $, useAtomValue } from 'jotai';
|
||||
import { loadable } from 'jotai/utils';
|
||||
//import './index.css';
|
||||
//@ts-ignore
|
||||
import k from './App.module.css';
|
||||
import { useEffect } from 'react';
|
||||
import { CalendarPricesChart } from './CalendarPricesChart';
|
||||
|
||||
const baseUrl = 'http://127.0.0.1:8234';
|
||||
export const baseUrl = 'http://127.0.0.1:8234';
|
||||
|
||||
/* The following are wrapped in atoms to prevent re-creating them if App() re-runs. */
|
||||
const $underlyingsUrl = $(`${baseUrl}/option_quotes/underlyings`);
|
||||
const $selectedUnderlying = $('');
|
||||
export const $underlyingsUrl = $(`${baseUrl}/option_quotes/underlyings`);
|
||||
export const $selectedUnderlying = $('');
|
||||
|
||||
const $quoteDatePickerUrl = $((get) => `${baseUrl}/option_quotes/${get($selectedUnderlying)}/quote_dates`);
|
||||
const $isQuoteDatePickerEnabled = $((get) => get($selectedUnderlying)!=='');
|
||||
const $selectedQuoteDate = $('');
|
||||
export const $quoteDatePickerUrl = $((get) => `${baseUrl}/option_quotes/${get($selectedUnderlying)}/quote_dates`);
|
||||
export const $isQuoteDatePickerEnabled = $((get) => get($selectedUnderlying)!=='');
|
||||
export const $selectedQuoteDate = $('');
|
||||
|
||||
const $strikePickerUrl = $((get) => `${baseUrl}/option_quotes/${get($selectedUnderlying)}/${get($selectedQuoteDate)}/strikes`);
|
||||
const $isStrikePickerEnabled = $((get) => get($selectedQuoteDate)!=='' && get($selectedUnderlying)!=='');
|
||||
const $selectedStrike = $('');
|
||||
export const $strikePickerUrl = $((get) => `${baseUrl}/option_quotes/${get($selectedUnderlying)}/${get($selectedQuoteDate)}/strikes`);
|
||||
export const $isStrikePickerEnabled = $((get) => get($selectedQuoteDate)!=='' && get($selectedUnderlying)!=='');
|
||||
export const $selectedStrike = $('');
|
||||
|
||||
const $frontMonthExpirationPickerUrl = $((get) => `${baseUrl}/option_quotes/${get($selectedUnderlying)}/${get($selectedQuoteDate)}/expirations`);
|
||||
const $isFrontMonthExpirationPickerEnabled = $((get) => get($selectedQuoteDate)!=='' && get($selectedUnderlying)!=='');
|
||||
const $selectedFrontExpiration = $('');
|
||||
export const $frontMonthExpirationPickerUrl = $((get) => `${baseUrl}/option_quotes/${get($selectedUnderlying)}/${get($selectedQuoteDate)}/expirations`);
|
||||
export const $isFrontMonthExpirationPickerEnabled = $((get) => get($selectedQuoteDate)!=='' && get($selectedUnderlying)!=='');
|
||||
export const $selectedFrontExpiration = $('');
|
||||
|
||||
export const $backMonthExpirationPickerUrl = $((get) => `${baseUrl}/option_quotes/${get($selectedUnderlying)}/${get($selectedQuoteDate)}/expirations`);
|
||||
export const $isBackMonthExpirationPickerEnabled = $((get) => get($selectedQuoteDate)!=='' && get($selectedUnderlying)!=='');
|
||||
export const $selectedBackExpiration = $('');
|
||||
|
||||
const $backMonthExpirationPickerUrl = $((get) => `${baseUrl}/option_quotes/${get($selectedUnderlying)}/${get($selectedQuoteDate)}/expirations`);
|
||||
const $isBackMonthExpirationPickerEnabled = $((get) => get($selectedQuoteDate)!=='' && get($selectedUnderlying)!=='');
|
||||
const $selectedBackExpiration = $('');
|
||||
|
||||
const $prices = $((get)=>{
|
||||
const selectedUnderlying = get($selectedUnderlying);
|
||||
const selectedStrike = get($selectedStrike);
|
||||
const selectedFrontExpiration = get($selectedFrontExpiration);
|
||||
const selectedBackExpiration = get($selectedBackExpiration);
|
||||
if(selectedUnderlying!=='' && selectedStrike!=='' && selectedFrontExpiration!=='' && selectedBackExpiration!==''){
|
||||
return fetch(`${baseUrl}/option_quotes/${selectedUnderlying}/${selectedStrike}/${selectedFrontExpiration}/${selectedBackExpiration}`).then(x=>x.json()).catch(()=>[]);
|
||||
}
|
||||
else{
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
});
|
||||
|
||||
function App() {
|
||||
const prices = useAtomValue($prices);
|
||||
|
||||
return (
|
||||
<div className={k.app}>
|
||||
<Header />
|
||||
@@ -52,7 +42,8 @@ function App() {
|
||||
<div className={k.picker}><label>Strike</label><Picker $url={$strikePickerUrl} $isEnabled={$isStrikePickerEnabled} $selectedOption={$selectedStrike}/></div>
|
||||
<div className={k.picker}><label>Front Expiration</label><Picker $url={$frontMonthExpirationPickerUrl} $isEnabled={$isFrontMonthExpirationPickerEnabled} $selectedOption={$selectedFrontExpiration} /></div>
|
||||
<div className={k.picker}><label>Back Expiration</label><Picker $url={$backMonthExpirationPickerUrl} $isEnabled={$isBackMonthExpirationPickerEnabled} $selectedOption={$selectedBackExpiration} /></div>
|
||||
<HistoricalImpliedVolatilityChart />
|
||||
<CalendarPricesChart />
|
||||
{/* <HistoricalImpliedVolatilityChart /> */}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import { Chart as ChartJS, Tooltip, Legend, LineElement, CategoryScale, LinearScale, PointElement } from "chart.js";
|
||||
import { Line } from 'react-chartjs-2';
|
||||
import { atom as $, useAtomValue } from 'jotai';
|
||||
import { loadable } from 'jotai/utils';
|
||||
import { useEffect } from "react";
|
||||
import { baseUrl, $selectedUnderlying, $selectedStrike, $selectedFrontExpiration, $selectedBackExpiration } from "./App";
|
||||
|
||||
ChartJS.register(LineElement, Tooltip, Legend, CategoryScale, LinearScale, PointElement);
|
||||
|
||||
export type CalendarPrice = {
|
||||
quote_date: string,
|
||||
price: number
|
||||
};
|
||||
|
||||
const $prices = loadable<Promise<Array<CalendarPrice>>>($(async (get)=>{
|
||||
const selectedUnderlying = get($selectedUnderlying);
|
||||
const selectedStrike = get($selectedStrike);
|
||||
const selectedFrontExpiration = get($selectedFrontExpiration);
|
||||
const selectedBackExpiration = get($selectedBackExpiration);
|
||||
if(selectedUnderlying!=='' && selectedStrike!=='' && selectedFrontExpiration!=='' && selectedBackExpiration!==''){
|
||||
return await fetch(`${baseUrl}/option_quotes/${selectedUnderlying}/${selectedStrike}/${selectedFrontExpiration}/${selectedBackExpiration}`).then(x=>x.json()).catch(()=>[]);
|
||||
}
|
||||
else{
|
||||
return [];
|
||||
}
|
||||
}));
|
||||
|
||||
export function CalendarPricesChart(){
|
||||
const prices = useAtomValue($prices);
|
||||
|
||||
useEffect(()=>{ console.log(prices); },[prices])
|
||||
if(prices.state === 'hasData'){
|
||||
return (<div>
|
||||
<Line
|
||||
datasetIdKey='id'
|
||||
data={{
|
||||
labels: prices.data.map((x)=>x.quote_date.substring(0,10)),
|
||||
datasets: [
|
||||
{//@ts-ignore
|
||||
id: 1,
|
||||
label: '',
|
||||
data: prices.data.map((x)=>x.price),
|
||||
},
|
||||
],
|
||||
}}
|
||||
/>
|
||||
</div>);
|
||||
}
|
||||
else {
|
||||
return (<></>);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user