Add Historial CalendarPrices Chart
This commit is contained in:
Vendored
+852
-743
File diff suppressed because it is too large
Load Diff
+21
-30
@@ -2,48 +2,38 @@ import Header from './Header';
|
|||||||
import { HistoricalImpliedVolatilityChart } from "./HistoricalImpliedVolatilityChart";
|
import { HistoricalImpliedVolatilityChart } from "./HistoricalImpliedVolatilityChart";
|
||||||
import { Picker } from './Picker';
|
import { Picker } from './Picker';
|
||||||
import { atom as $, useAtomValue } from 'jotai';
|
import { atom as $, useAtomValue } from 'jotai';
|
||||||
|
import { loadable } from 'jotai/utils';
|
||||||
//import './index.css';
|
//import './index.css';
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
import k from './App.module.css';
|
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. */
|
/* The following are wrapped in atoms to prevent re-creating them if App() re-runs. */
|
||||||
const $underlyingsUrl = $(`${baseUrl}/option_quotes/underlyings`);
|
export const $underlyingsUrl = $(`${baseUrl}/option_quotes/underlyings`);
|
||||||
const $selectedUnderlying = $('');
|
export const $selectedUnderlying = $('');
|
||||||
|
|
||||||
const $quoteDatePickerUrl = $((get) => `${baseUrl}/option_quotes/${get($selectedUnderlying)}/quote_dates`);
|
export const $quoteDatePickerUrl = $((get) => `${baseUrl}/option_quotes/${get($selectedUnderlying)}/quote_dates`);
|
||||||
const $isQuoteDatePickerEnabled = $((get) => get($selectedUnderlying)!=='');
|
export const $isQuoteDatePickerEnabled = $((get) => get($selectedUnderlying)!=='');
|
||||||
const $selectedQuoteDate = $('');
|
export const $selectedQuoteDate = $('');
|
||||||
|
|
||||||
const $strikePickerUrl = $((get) => `${baseUrl}/option_quotes/${get($selectedUnderlying)}/${get($selectedQuoteDate)}/strikes`);
|
export const $strikePickerUrl = $((get) => `${baseUrl}/option_quotes/${get($selectedUnderlying)}/${get($selectedQuoteDate)}/strikes`);
|
||||||
const $isStrikePickerEnabled = $((get) => get($selectedQuoteDate)!=='' && get($selectedUnderlying)!=='');
|
export const $isStrikePickerEnabled = $((get) => get($selectedQuoteDate)!=='' && get($selectedUnderlying)!=='');
|
||||||
const $selectedStrike = $('');
|
export const $selectedStrike = $('');
|
||||||
|
|
||||||
const $frontMonthExpirationPickerUrl = $((get) => `${baseUrl}/option_quotes/${get($selectedUnderlying)}/${get($selectedQuoteDate)}/expirations`);
|
export const $frontMonthExpirationPickerUrl = $((get) => `${baseUrl}/option_quotes/${get($selectedUnderlying)}/${get($selectedQuoteDate)}/expirations`);
|
||||||
const $isFrontMonthExpirationPickerEnabled = $((get) => get($selectedQuoteDate)!=='' && get($selectedUnderlying)!=='');
|
export const $isFrontMonthExpirationPickerEnabled = $((get) => get($selectedQuoteDate)!=='' && get($selectedUnderlying)!=='');
|
||||||
const $selectedFrontExpiration = $('');
|
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() {
|
function App() {
|
||||||
const prices = useAtomValue($prices);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={k.app}>
|
<div className={k.app}>
|
||||||
<Header />
|
<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>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>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>
|
<div className={k.picker}><label>Back Expiration</label><Picker $url={$backMonthExpirationPickerUrl} $isEnabled={$isBackMonthExpirationPickerEnabled} $selectedOption={$selectedBackExpiration} /></div>
|
||||||
<HistoricalImpliedVolatilityChart />
|
<CalendarPricesChart />
|
||||||
|
{/* <HistoricalImpliedVolatilityChart /> */}
|
||||||
</div>
|
</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 (<></>);
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-1
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"jsx": "react-jsx"
|
"jsx": "react-jsx",
|
||||||
|
"lib": ["DOM", "DOM.Iterable", "ES2017"]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user